﻿
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>文档</title>
    <link href="../content/css/semantic/semantic.min.css" rel="stylesheet">
    <link href="../content/css/oscTree.css" rel="stylesheet">
    <link href="../content/css/markdown.css" rel="stylesheet">
    <link href="../content/css/index.css" rel="stylesheet">
</head>
<body>
    <div class="ui container">
        <div id="project-title">
            <div class="title-wrap">
                <div class="left">
                    <i class="icon eye"></i>
                    文档预览:
                    <span id="preview-title"></span>
                </div>
                <div class="right">
                    Export by Gitee
                </div>
            </div>
        </div>

        <div class="ui container" id="wiki-preview-container">
            <div id="wiki-preview">
                <div class="ui segment">
                    <div class="ui grid page">
                        <div class="three wide column doc-list">
                            <div class="title">
                                <a id="ex-all">
                                    收缩全部章节
                                </a>
                            </div>
                            <div class="ztree" id="tree"></div>
                        </div>
                        <div class="thirteen wide column doc-content">
                            <div id="page-detail">
                                <div class="title">
                                </div>
                                <div class="content markdown-body">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
<script src="../content/js/jquery.min.js"></script>
<script src="../content/js/ztree.all.js"></script>
<script src="../content/js/jquery.ztree.exhide.min.js"></script>
<script>
    var zTreeObj; var expandStatus = true; $(document).ready(function () { var setting = { view: { showLine: true, showIcon: true }, callback: { onClick: function (e, treeId, treeNode) { if (treeNode !== null && !treeNode.isParent && typeof (treeNode.children) === "undefined") { var sort_id = treeNode.sort_id; var content = json_data.content; for (var c in content) { if (c == sort_id) { $("#page-detail .title").html(treeNode.name); $("#page-detail .content").html(content[c]); return false } } } else { zTreeObj.expandNode(treeNode) } } }, data: { simpleData: { enable: true } } }; zTreeObj = $.fn.zTree.init($("#tree"), setting, json_data.title); var first_content = json_data.title[0]; $("#page-detail .title").html(first_content.name); $("#page-detail .content").html(json_data.content[first_content.sort_id]); $("#preview-title").html(json_data.preview_title); $("#ex-all").on("click", function (e) { zTreeObj.expandAll(!expandStatus); expandStatus = !expandStatus; if (expandStatus) { $(this).text("收缩全部章节") } else { $(this).text("展开全部章节") } }) });
</script>
<script>var json_data = { "preview_title": "RuiJi.Net", "title": [{ "id": "介绍", "pId": 0, "name": "介绍", "parent": null, "order": 0, "sort_id": 416749, "extname": ".md", "isParent": false, "isHidden": false, "content": "![](https://secure.gravatar.com/avatar/2d659788ba318c53b639092b4a4e27b8?s=100\u0026r=g\u0026d=retro \"\")\n\n### 介绍\n\n#### RuiJi.Net 是什么?\n---\n\nRuiJi.Net是一个可以分布式部署的爬虫框架，使用C#编写，项目的最终目的是可以对大量的网站进行自动更新检查及抓取，使用者可以设置新闻源的检查时间间隔，在检测到新闻源更新后，会将更新的地址发送给下载节点，再由抽取节点对数据进行提取及清洗。\n\nRuiJi.Net支持自管理Cookie,并且自动维护不同浏览器标识的Cookie，这意味着您可以在使用独立IP的基础上，虚拟出任意多的Cookie. RuiJi.Net同样支持使用抓取服务器上的IP进行轮询抓取，并且也可以使用代理服务器。\n\nRuiJi.Net具有自己的抽取模型，称为RuiJi Expression（RuiJi表达式），您可以使用RuiJi表达式定义抽取模型，并对需要提取的元数据进行精确清洗。RuiJi表达式可以存储为文本文档、数据库及高速缓存中。\n\nRuiJi.Net计划在将来提供PHP,JAVA等其他语言的SDK,以方便调用框架API.\n\n\u003E 该教程假设你已经具有一定的爬虫基础，且具有css,html,regex,xpath,json的处理经验，如果您刚开始接触爬虫，请先了解爬虫的基本知识，也许在将来，我们会准备些这方面的资料。" }, { "id": "RuiJi表达式介绍", "pId": "0f00588", "name": "RuiJi表达式介绍", "parent": "RuiJi表达式", "order": 0, "sort_id": 485777, "extname": ".md", "isParent": false, "isHidden": false, "content": "RuiJi表达式是为了快速添加抽取规则，实现规则与程序运行分离的一种方式，RuiJi表达式尽量的简单、易懂、配置灵活。\n\nRuiJi表达式遵循RuiJi.Net的抽取模型，表达式所描述的抽取结构与RuiJi.Net的抽取模型一致。\n\nRuiJi表达式可以存储于文本文件、数据库或高速缓存中，在需要进行抽取时再进行读取，这意味着您不需要重新启动程序，可以在任意需要的时刻更改表达式内容。\n\n\u003E 在日后我们会让每一个抽取节点都可以缓存RuiJi表达式，并在需要时接收更改通知，对规则进行更新。" },{"id":"开始安装","pId":"087db63","name":"开始安装","parent":"安装","order":0,"sort_id":481200,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net有三种运行模式，分别为本地模式，伪分布模式，全分布模式。\n\n安装.net core 2.1环境\n\n您需要从github或gitee中获取源码，编译Ruiji.Net项目。\n\n\u003E 您还可以通过网盘下载已编译好的项目，地址为 https://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw 访问密码 ef8d\n\n##### 如果您自行编译项目，请按如下操作进行\n\n1. 访问 https://github.com/zhupingqi/RuiJi.Net 或 https://gitee.com/zhupingqi/RuiJi.Net 下载Zip包，解压到您的目标文件夹\n \n2. 使用 vs2017 打开项目，还原依赖包并编译项目。\n \n3. 编译成功后使用 vs2017 发布项目。\n\n4. 使用控制台进入发布文件夹，运行以下命令，启动项目\n```\ndotnet RuiJi.Net.Cmd.dll\n```\n"},{"id":"结构","pId":"3508e27","name":"结构","parent":"抽取模型","order":0,"sort_id":482337,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 将需抽取的目标进行了结构化处理，每一个需要抽取的目标页面被划分为以下结构 分别为 Block、Tile、Meta。这在RuiJi.Net中被称为抽取器。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/06/1-3.png \"\")\n"},{"id":"架构","pId":"b29e3c4","name":"架构","parent":"深入了解RuiJi.Net","order":0,"sort_id":416750,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 的设计目标是对大量的网站进行更新检查和快速抓取，抽取，清洗，这在最开始的介绍中已经提及。为了达到这个目标，RuiJi.Net将更新检查，下载，抽取清洗划分为不同的模块，这些模块分别运行在RuiJi.Net的不同节点上。RuiJi.Net的最终目标，是在全分布模式下，提供高可用性集群(HA)，以保障业务的连贯性。RuiJi.Net 可用用于舆情监测、企业新闻监测、自建搜索引擎等对实时要求教高的场景。\n\n以下为各个节点功能简介\n\n1. 抓取代理节点：维护抓取节点服务器列表，分配抓取任务\n2. 抓取节点：负责下载指定地址源码\n3. 抽取代理节点：维护抽取节点服务器列表，分配抽取任务\n4. 抽取节点：根据规则对源码进行抽取，清洗\n5. 新闻源代理节点：存储新闻源列表及规则列表，匹配提取规则\n6. 新闻源节点：检查新闻源更新，请求抓取任务，转发抽取请求，保存抽取结果\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/05/2-2.png)"},{"id":"界面介绍","pId":"5811dfb","name":"界面介绍","parent":"管理员UI","order":0,"sort_id":495933,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 提供基于Web的管理界面，管理界面地址为任意您在config中配置节点的baseUrl。通过管理界面，您可以观测到服务器的运行状态，日志，集群状态，并可以通过管理界面录入需要监测的订阅源地址，抽取规则。管理界面还提供了对抓取到的结果进行简单的预览，在设置选项卡中，您可以设置一些RuiJi.Net需要的参数。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/1.png)\n\n\u003E RuiJi.Net的管理界面中的选项卡分为两种类型，状态及日志显示的是当前节点的相关信息，集群、订阅源、抓取结果、设置从任意节点访问的结果是一样的，RuiJi.Net通过节点路由，将消息转发给相关节点进行处理。"},{"id":"节点","pId":"5356af4","name":"节点","parent":"管理员UI/设置","order":0,"sort_id":518401,"extname":".md","isParent":false,"isHidden":false,"content":"设置选项卡中的节点设置用来设置订阅源节点需要检查的订阅源范围以及抓取节点可以使用的IP范围。\n\u003E 此选项卡在伪分布式、全分布式的模式可见\n\n### 设置订阅源范围\n设置订阅源节点检测的订阅源范围，根据ID正序排列，每页取50条。例：节点Feed1输入设置1,3，那么节点Feed1在检查订阅源时，就会取出记录中的前50条及101条-150条，共100条订阅源去进行检查。\n\u003E 多个节点不可重复检测同一页码\n\n### 设置抓取节点IP范围\n设置抓取节点在抓取页面时可以使用的IP地址范围，在爬取数据时，会根据指定的IP进行IP轮询抓取。 \n\n\u003E 请在第一次启动时务必为每个节点设置至少一个可用IP，如果无设置将无法正常下载任何内容\n\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/15.png)\n"},{"id":"选择器类型","pId":"5da56ab","name":"选择器类型","parent":"选择器","order":0,"sort_id":485678,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 的选择器(Selector)被用来抽取所属结构的内容，通常为一个或多个，下一个选择器处理的是上一个选择器的处理结果，通过逐层处理的方式，我们可以将抽取结果进行精细化抽取，以达到最终需要的抽取结果。\n\nRuiJi.Net 的选择器有以下类型\n\n|类型|说明|\n| :-: | :-:  |\n|CSS| 样式选择器，类似于JQuery |\n|REGEX|正则选择器|\n|REGEXSPLIT|分割选择器，支持正则分割|\n|TEXTRANGE|文本区域选择器|\n|EXCLUDE|排除选择器|\n|REGEXREPLACE|替换选择器|\n|JPATH|JSON选择器|\n|XPATH|xpath选择器，用来处理xml文档|\n|CLEAR|清除选择器，清理html标签|\n|EXPRESSION|表达式选择器，用来匹配地址|\n|SELECTORPROCESSOR|函数选择器，通过自定义函数处理选择器结果|"},{"id":"起步","pId":"0f00588","name":"起步","parent":"RuiJi表达式","order":1,"sort_id":485784,"extname":".md","isParent":false,"isHidden":false,"content":"如上所述，RuiJi表达式遵循RuiJi.Net的抽取结构，在RuiJi.Net中的抽取器包含Block、Tile、Meta, 在RuiJi表达式中使用[block]、[tile]、[meta]表示。\n\n##### 一个最简单的抽取表达式定义如下\n\n```\n[block]\n#recommend\ncss #topsOfRecommend\n```\n\n这个表达式定义了一个抽取器，抽取器的名称是recommend, 抽取器定义了一个css选择器，选择id为topsOfRecommend的outerHtml做为block抽取器的最终抽取内容。\n\n\u003E 抽取器都可以包含名称，但对于block和tile来说，并不是必需的，如果需要定义抽取器的名称，则名称描述必须紧跟在抽取器之后（新行），并且以#开头。\n\n##### 具有tile的block\n\n```\n[block]\n#recommend\ncss #topsOfRecommend:ohtml\n\n[tile]\n#tile\ncss .box-aw\n```\n\n\u003E 这里block的css选择器末尾加上了:ohtml，这与上一个示例一样，都是选择id为topsOfRecommend的outerHtml做为block抽取器的最终抽取内容。在这里第一个示例是简写，在选择结果为dom的情况下，如果没有指明选择后缀会默认使用outerHtml作为选择结果。可用后缀还包括html,text。\n\n这里的tile抽取器抽取的内容是block抽取器的结果，也就是id为topsOfRecommend的outerHtml。在这个结果中选择样式为.box-aw的dom作为tile选择器的结果，这个结果为1个或多个。\n\n##### 继续在tile结果中抽取元数据\n\n\n```\n[block]\n#BlockName\ncss #topsOfRecommend:ohtml\n\n[tile]\n#titlename\ncss .box-aw\n\n\t[meta]\n\t#title\n\tcss .blog-title-link:[title]\n\n\t#author\n\tcss .blog-footer-box \u003E span:first:text\n\n\t#postdate\n\tcss .blog-footer-box \u003E span:eq(2):text\n\n\t#reads_i\n\tcss .blog-footer-box \u003E span:last:text\n\tregS / / 1\n```\n\n\u003E 这里的meta会向后缩进，以表示这个抽取器是tile的子抽取器，如果不缩进的话，则表示这个抽取器是block的抽取器。向后缩进的单位是一个制表符。\n\nmeta可以选择出多组数据，并且必须具有名称，每个需要抽取的元素之间需要一个空行。在本示例的中meta是处理tile的每一个抽取结果，meta的处理结果是一个字典。\n\n\u003E 也许在未来我们会提供一个RuiJi表达式的编译器，以方便大家录入RuiJi表达式"},{"id":"087db63","pId":0,"name":"安装","parent":"","sort_id":481494,"order":1,"isParent":true,"extname":null,"open":true},{"id":"Linux 安装RuiJi.Net","pId":"087db63","name":"Linux 安装RuiJi.Net","parent":"安装","order":1,"sort_id":569215,"extname":".md","isParent":false,"isHidden":false,"content":"安装Linux .net core 2.1环境\n\n您需要从github或gitee中获取源码，编译Ruiji.Net项目。\n\n\u003E 您还可以通过网盘下载已编译好的项目，地址为 https://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw 访问密码 ef8d\n\n##### 如果您自行编译项目，请按如下操作进行\n\n1. 访问 https://github.com/zhupingqi/RuiJi.Net 或 https://gitee.com/zhupingqi/RuiJi.Net 下载Zip包，解压到您的目标文件夹\n \n2. 使用 vs2017 打开项目，还原依赖包并编译项目。\n \n3. 编译成功后使用 vs2017 发布项目。\n \n4. 将发布好的项目文件夹上传到Linux服务器\n \n5. 进入Ruiji.Net目录，执行以下代码，启动项目\n```\ndotnet Ruiji.Net.Cmd.dll\n```\n\n\u003E 您可以使用supervisord守护进程，使Ruiji.Net进入后台运行。"},{"id":"状态","pId":"5811dfb","name":"状态","parent":"管理员UI","order":1,"sort_id":496673,"extname":".md","isParent":false,"isHidden":false,"content":"状态选项卡显示当前节点的节点类型和状态。在这里您可以观测到如下内容。\n\n1. 节点类型,包括：STANDALONE,CRAWLER,CRAWLERPROXY,EXTRACTOR,EXTRACTORPROXY,FEED,FEEDPROXY\n\u003E 在单机模式下，节点的类型为STANDALONE\n2. 节点的启动时间\n3. 节点运行的框架及服务器硬件环境\n4. 节点所使用RuiJi.Net类库版本\n5. 节点资源的消耗情况，包括：内存、CPU使用率，网卡\n6. 作者近一月对项目的更新信息。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/2-2.png)"},{"id":"订阅源","pId":"81b9a28","name":"订阅源","parent":"管理员UI/订阅源","order":1,"sort_id":497408,"extname":".md","isParent":false,"isHidden":false,"content":"### 订阅源\n\n通过订阅源选项卡，您可以对需要抓取的订阅源进行添加、修改、查询等操作，并且可以直接进行规则测试，抓取模拟。\n\n\u003E 在伪分布和全分布模式下，访问任一节点，您都可以对订阅源进行操作，并且这些操作都会被路由到订阅源代理节点进行处理\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/5.png)\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/6.png)"},{"id":"函数","pId":"5356af4","name":"函数","parent":"管理员UI/设置","order":1,"sort_id":504402,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 中的函数可以被用来处理Url地址或选择器结果，函数分为两种类型：URLFUNCTION 和 SELECTORPROCESSOR\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/16.png)"},{"id":"选择器介绍","pId":"5da56ab","name":"选择器介绍","parent":"选择器","order":1,"sort_id":485705,"extname":".md","isParent":false,"isHidden":false,"content":"### Css 选择器\n\ncss选择器使用的类库是CsQuery, CsQuery提供了类似JQuery的方法，通过css选择器来处理html页面。在RuiJi.Net中通常css选择器会作为Selectors的第一个选择器，用来定位选择区域。\n\n### Regex 选择器\n\nregex选择器是使用正则表达式来抽取内容，在RuiJi.Net可以通过配置提取表达式结果或分组结果。\n\n### RegexSplit 选择器\n\n以正则表达式分割字符串，并提取其中的指定索引的结果，可以指定多个\n\n### TextRange 选择器\n\n文本区域选择器，该选择器通过定义文本开始的字符串和文本结束的字符串，来抽取开始和结束文本区域中间的内容。\n\n### Exclude 选择器\n排除选择器用来排除指定的文本内容。需排除的内容以正则表达式定义。\n\n### RegexReplace 选择器\n正则替换选择器，被用来将匹配出的结果替换成目标结果。\n\n### JPath 选择器\nJsonPath 选择器被用来处理Json格式的文档。\n\n### XPath 选择器\nXPath 选择器被用来处理XML文档\n\n### Clear 选择器\nClear选择器会自动清除一些Html源文件的标签，包含:script、style、iframe、input、textarea、select、form及注释等。\n\n### Expression 选择器\n表达式选择器通常使用通配符抽取需要的链接地址。\n\n### SELECTORPROCESSOR 选择器\nSELECTORPROCESSOR 选择允许用户调用外部已经定义好的函数处理一些特殊的抽取结果，例如抽取出的时间是 xx 分钟前。"},{"id":"多个选择器","pId":"0f00588","name":"多个选择器","parent":"RuiJi表达式","order":2,"sort_id":485813,"extname":".md","isParent":false,"isHidden":false,"content":"这里我们以抽取出栏目名称为例，假设一个页面的栏目的源码如下\n\n\n```\n\u003Ctd\u003E\n    \u003Cdiv style=\"width:616px; float:left;\" class=\"f12 black\"\u003E\n\t \u003Cul style=\"margin:0; padding:0;\"\u003E\n\t  \u003Cli style=\"float:left; width:120px; text-align:right;\"\u003E法制网首页\u0026gt;\u0026gt;\u003C/li\u003E\n\t  \u003Cli style=\"float:left; width:350px; text-align:left;\"\u003E\n              \u003Cspan style=\"padding:5px 0px 5px 15px;\"\u003E\n\t        \u003Ca href=\"../../../node_34228.htm\" target=\"_blank\" class=\"f12 black\"\u003E评论频道\u003C/a\u003E\n                \u003Cfont class=\"f12 black\"\u003E\u0026gt;\u0026gt;\u003C/font\u003E\n                \u003Ca href=\"../../../node_34252.htm\" target=\"_blank\" class=\"f12 black\"\u003E法治时评\u003C/a\u003E\n\t      \u003C/span\u003E\n            \u003C/li\u003E\n\t \u003C/ul\u003E\n    \u003C/div\u003E\n\u003C/td\u003E\n```\n\n我们使用如下的RuiJi表达式对栏目进行抽取，同时需要去除 法制网首页\u003E\u003E 的文本，那么选择器定义可以如下\n\n```\n[meta]\n#railling\ncss div.f12:text\nex /\\s+法制网首页\u003E\u003E/ -b\nregR /\u003E\u003E/ \u003E\n```\n\n在这里第一个选择器首先选择出div.f12的文本，结果如下\n\n```\n 法制网首页\u003E\u003E 评论频道\u003E\u003E法治时评\n```\n\n然后使用排除选择器在文本开始部分排除掉 法制网首页\u003E\u003E （-b是排除开始文本的意思） 得到结果如下\n\n```\n 评论频道\u003E\u003E法治时评\n```\n\n再次我们需要将 \u003E\u003E 替换为 \u003E 最终结果如下\n\n\n```\n评论频道\u003E法治时评\n```\n\n当然我们也可以这样去抽取栏目\n\n\n```\n[meta]\n#railling\ncss div.f12 span:text\nregR /\u003E\u003E/ \u003E\n```\n\n这与上面的结果是一致的。\n\n"},{"id":"本地模式","pId":"087db63","name":"本地模式","parent":"安装","order":2,"sort_id":416748,"extname":".md","isParent":false,"isHidden":false,"content":"#### 本地模式\nRuiJi.Net的本地模式常用于演示效果和测试\n\n1. 首先确保 运行目录下具有 ruiji.json 配置文件\n2. ruiji.json 的配置如下（如果您没有修改过的话，这些配置是默认的）\n\n```\n{\n  \"setting\": {\n    \"ruiJiServer\": \"localhost:36000\",\n    \"docServer\": \"localhost:80\"\n  },\n  \"nodes\": [\n  ]\n}\n```\n\n- ruiJiServer 是RuiJi.Net的管理员页面地址\n- docServer 是RuiJi.Net的帮助文档页面，如果不需要，您可以注释掉这部分\n\n3. 运行 dotnet RuiJi.Net.Cmd.dll \n\n如果您看到如下信息，恭喜您，启动成功\n\n```\nHosting environment: Production\n......\nNow listening on: http://192.168.31.32:80\nApplication started. Press Ctrl+C to shut down.\nHosting environment: Production\n......\nNow listening on: http://192.168.31.32:36000\nApplication started. Press Ctrl+C to shut down.\n2018-07-29 11:19:52,015 [1] INFO  - 192.168.31.32:36000 feed scheduler starting\n2018-07-29 11:19:52,030 [1] INFO  - 192.168.31.32:36000 feed scheduler started\n2018-07-29 11:19:52,033 [1] INFO  - Start WebApiServer At http://192.168.31.32:36000 with STANDALONE node\n......\n```\n\n在浏览器中输入控制台中提示的地址，以上为例的话，输入 http://192.168.31.32:36000\n您将看到类似如下的管理页面\n\n ![](http://www.ruijihg.com/wp-content/uploads/2018/06/4-3.png)"},{"id":"Selectors","pId":"3508e27","name":"Selectors","parent":"抽取模型","order":2,"sort_id":482347,"extname":".md","isParent":false,"isHidden":false,"content":"每一个RuiJi.Net的抽取器都包含Selectors, Selectors是被用来定义所属抽取器需抽取内容的选择器。Selectors是由Selector组成，每个Selector都依赖上一个Selector的处理结果，也就是下一个Selecor相对与上一个Selector会抽取更精细的内容. \n\n\u003E 如果所属抽取器没有定义Selectors，抽取器的抽取内容会被默认为返回整个文档内容或父抽取器的抽取结果。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/2.png \"\")"},{"id":"5811dfb","pId":0,"name":"管理员UI","parent":"","sort_id":482334,"order":2,"isParent":true,"extname":null,"open":true},{"id":"日志","pId":"5811dfb","name":"日志","parent":"管理员UI","order":2,"sort_id":497181,"extname":".md","isParent":false,"isHidden":false,"content":"日志选项卡显示了当前节点的日志，包括节点启动日志，任务调度信息及抓取，抽取日志。日志选项卡的日志最多只显示最近1000条，如果您需要查看更多的日志，请在对应节点的运行目录下的logs文件夹里面查看。\n\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/4-1.png)"},{"id":"编辑订阅源","pId":"81b9a28","name":"编辑订阅源","parent":"管理员UI/订阅源","order":2,"sort_id":500986,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或订阅源的编辑按钮，可进入订阅源详细编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/27.png)\n\n在Address中，您可以填写地址函数，以{# #}包裹。您将在以后的章节中看到地址函数的介绍。图中所示函数的功能为，每次扫描订阅源的前两页。\n\n请求方法为POST时需设置Content-Type及Data参数。\n\nDialog中各字段属性对照表如下\n\n|字段|描述|特性|\n| :-: | :-: | :-: |\n|Site name|订阅源站点名称|支持关键词搜索|\n|Remark|备注信息|支持关键词搜索|\n|Address|地址链接|支持关键词搜索|\n|Method|请求方法|GET POST|\n|Content-Type|内容类型|application/x-www-form-urlencoded\u003Cbr/\u003Eapplication/json|\n|Data|请求参数|根据内容类型设置不同格式的请求参数|\n|UA|浏览器User-Agent|为空则随机使用Setting中设置的UA\u003Cbr/\u003E如果Setting中无UA设置则默认使用Ruiji自带|\n|Hearders|请求标头|以回车分割|\n|Genre|订阅源类型|方便日后进行订阅源分类|\n|Type|地址返回值格式|仅记录，无实际用途|\n|RuiJi Exp|Ruiji表达式|详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BB%8B%E7%BB%8D\u0026parent=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F\" target=\"blank\"\u003ERuiji表达式介绍\u003C/a\u003E|\n|Delay|延迟执行时间|订阅源更新后延迟多久开始下载目标链接|\n|Scheduling|扫描时间间隔|Cron表达式\u003Cbr/\u003E可选择选项自动生成也可填写|\n|Status|是否开启||\n|RunJs|是否执行页面JS|如果选择ON,\u003Cbr/\u003ERuiJi.Net将会使用无头浏览器对目标页面进行访问|\n|WaitDom|执行页面JS时等待某个Dom元素|css selector形式|"},{"id":"编辑函数","pId":"5356af4","name":"编辑函数","parent":"管理员UI/设置","order":2,"sort_id":518882,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或函数的编辑按钮，可进入函数编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/17.png)\n\nDialog中各字段属性对照表如下\n\n|字段|描述|特性|\n| :-: | :-: | :-: |\n|Name|函数名称|以供调用时使用|\n|Code|具体执行代码|暂时只支持C#代码编写|\n|Type|函数类型|详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=URLFUNCTION\u0026parent=%E7%AE%A1%E7%90%86%E5%91%98UI%2F%E8%AE%BE%E7%BD%AE\" target=\"_blank\"\u003EURLFUNCTION\u003C/a\u003E和\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=SELECTORPROCESSOR\u0026parent=%E7%AE%A1%E7%90%86%E5%91%98UI%2F%E8%AE%BE%E7%BD%AE\" target=\"_blank\"\u003ESELECTORPROCESSOR\u003C/a\u003E|\n|Smaple|使用示例||"},{"id":"表达式选择器","pId":"0f00588","name":"表达式选择器","parent":"RuiJi表达式","order":3,"sort_id":485823,"extname":".md","isParent":false,"isHidden":false,"content":"##### Css 选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|css tag:[xxx]|选择属性|\n|css tag:text|选择文本|\n|css tag:ohtml|选择outerHtml|\n|css tag:html|选择innerHtml|\n|css dd:[class=’f12 balck02 yh’] + dd:text|选择tag为dd,class为‘f12 balck01 yh’紧邻的dd的文本|\n\n##### Exclude 排除选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|ex /abc/ -b|在文本开始排除|\n|ex /abc/ -a|在文本任意位置排除|\n|ex /abc/ -e|在文本结尾排除|\n\n\u003E /abc/为正则表达式,以下以/开头再以/结尾的字符串均表示正则\n\n##### Expresssion 通配符选择器（仅适用于网址提取）\n\n|表达式|说明|\n| :-: | :-:  |\n|exp http://www.ruijihg.com/*|使用通配符匹配任何以http://www.ruijihg.com/开头的网址|\n|exp http://www.ruijihg.com/???|使用通配符匹配以http://www.ruijihg.com/开头，后面跟3个字符的网址|\n\n##### Regex 正则选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|reg /abc/|匹配正则结果|\n|reg /abc(.*)/ 1|匹配正则分组结果 取出第n个结果|\n\n##### RegexSplit 分割选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|regS /abc/ 3|以正则分割字符串 取出第n个结果|\n\n##### RegexReplace 替换选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|regR /abc/ 123|替换匹配出的正则结果|\n\n##### TextRange 文本区域选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|text /abc/ /edf/|取出以/abc/开头，/edf/结尾中的字符串|\n\n##### XPath 选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|xpath /bookstore/book[1]|xpath|\n\n##### JsonPath 选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|jpath $..url|jsonpath|\n\n##### SELECTORPROCESSOR 选择器\n\n|表达式|说明|\n| :-: | :-:  |\n|proc name|执行名称为name的函数|"},{"id":"伪分布模式","pId":"087db63","name":"伪分布模式","parent":"安装","order":3,"sort_id":481199,"extname":".md","isParent":false,"isHidden":false,"content":"伪分布模式需要使用zookeeper,首先安装如下步骤安装zookeeper\n\n1. 访问 http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/\n2. 下载ZooKeeper压缩包，并解压到RuiJi.Net的运行目录\n\n\u003E 如果需要更改zookeeper的数据目录，请修改zookeeper下/conf/zoo.cfg dataDir\n\n```\n# The number of milliseconds of each tick\ntickTime=2000\n# The number of ticks that the initial \n# synchronization phase can take\ninitLimit=10\n# The number of ticks that can pass between \n# sending a request and getting an acknowledgement\nsyncLimit=5\n# the directory where the snapshot is stored.\n# do not use /tmp for storage, /tmp here is just \n# example sakes.\ndataDir=e:\\\\zookeeper\\\\data\n#dataLogDir=e:\\\\zookeeper\\\\log\n# the port at which the clients will connect\nclientPort=2181\n#\n# Be sure to read the maintenance section of the \n# administrator guide before turning on autopurge.\n#\n# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance\n#\n# The number of snapshots to retain in dataDir\n#autopurge.snapRetainCount=3\n# Purge task interval in hours\n# Set to \"0\" to disable auto purge feature\n#autopurge.purgeInterval=1\n```\n3. 在ruiji.json里面增加zkPath如下,其中value为ZooKeeper在RuiJi.Net运行目录下的文件夹名称，如果以前配置过本地模式，可以把ruiJiServer注释掉\n4. 在nodes节点下增加如下配置\n\n```\n{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\" \n  },\n  \"nodes\": [\n     {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    },\n    {\n      \"baseUrl\": \"localhost:36001\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:36002\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37001\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37002\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38001\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38002\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    }\n  ]\n}\n```\n\n5. 启动RuiJi.Net，您将看到很多的输出日志，程序会首先会启动ZooKeeper, 然后按照配置文件，逐个启动对应的节点。\n\n```\nxxxx Start WebApiServer At http://192.168.31.196:37000 with ExtractorPROXY node\n......\nxxxx Start WebApiServer At http://192.168.31.196:36001 with CRAWLER node\n......\nplease e to exit!\n```\n如果您看到以上信息的最后一条，那么您就可以打开浏览器，输入任何在控制台中输出的节点网址，访问RuiJi.Net的管理网站\n\n在伪分布和全分布的模式下，管理网站的导航菜单会出现节点和集群的选项卡\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/06/3-3.png)"},{"id":"Block","pId":"3508e27","name":"Block","parent":"抽取模型","order":3,"sort_id":482340,"extname":".md","isParent":false,"isHidden":false,"content":"### Block 抽取器\n\nBlock为RuiJi.Net抽取模型中最基础的单位，Block负责定位抽取区域，Block下的Tile和Meta会在Block抽取结果中进行抽取，Block下的Selectors为Block抽取器的选择器。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/bb647a1f149e9887c5858c1f90725945a53.png \"\")\n\n\nBlock抽取器下面还可以再包含多个Block,在Block中以Blocks表示。\n\n\u003E 使用Block定位抽取区域的原因是源页面可能包含多个重复区域，而我们只对其中的部分感兴趣，这样我们可以仅对感兴趣的区域进行抽取，忽略其他的区域。如上所示，也许我们只对最新推荐感兴趣，而其他的今日热门，本周热门等我们不需要进行抽取。"},{"id":"节点","pId":"5811dfb","name":"节点","parent":"管理员UI","order":3,"sort_id":497064,"extname":".md","isParent":false,"isHidden":false,"content":"节点选项卡用来展示ZooKeeper中的内容，包括ZooKeeper的树形结构，ZooKeeper各个路径上保存的信息。您也可以在这里查看设置的抓取节点可以使用的IP范围，及Feed节点需要检查的订阅源范围。这两项设置您可以在设置选卡的Node下进行设置。\n\n\u003E 此选项卡在伪分布式、全分布式的模式可见\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/26.png)"},{"id":"订阅源测试","pId":"81b9a28","name":"订阅源测试","parent":"管理员UI/订阅源","order":3,"sort_id":500989,"extname":".md","isParent":false,"isHidden":false,"content":"Dialog中的Test按钮可以测试您的RuiJi表达式的抽取结果, 如下图所示\n\u003E如果是伪分布式或全分布式模式，请先前往Setting \u003E Node设置好抓取节点可用IP\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/9.png)\n\nDownload Target可下载目标地址，并以对应的格式保存于服务器上，如下图所示\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/10.png)\n\n\u003E RuiJi.Net通过固定时间间隔，访问订阅源，并通过算法检查订阅源的更新链接地址，订阅源的选择结果必须为链接地址，如果您不这么做的话，RuiJi.Net在下载完订阅源之后，将不会做任何操作。"},{"id":"函数测试","pId":"5356af4","name":"函数测试","parent":"管理员UI/设置","order":3,"sort_id":520174,"extname":".md","isParent":false,"isHidden":false,"content":"点击Test按钮，可根据您的使用示例测试函数结果。如下图所示\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/19.png)"},{"id":"类型转换","pId":"0f00588","name":"类型转换","parent":"RuiJi表达式","order":4,"sort_id":485826,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net 的抽取器可以将选择器处理结果转换为目标数据类型，类型转换是透过在抽取器名称后加后缀完成的，以下列表为抽取器名称可用后缀及其转换类型\n\n|后缀|目标转换类型|\n| :-: | :-:  |\n|*_i|int|\n|*_s|string|\n|*_l|long|\n|*_b|bool|\n|*_f|float|\n|*_d|double|\n|*_dt|datetime|\n\n\u003E 如果不指定后缀，抽取器会默认返回字符串类型，如果转换发生异常，抽取器同样会返回字符串类型\n\n以下为一个简单的示例\n\n\n```\n[meta]\n#title\ncss .blog-title-link:[title]\n\n#author\ncss .blog-footer-box \u003E span:first:text\n\n#postdate_dt\ncss .blog-footer-box \u003E span:eq(2):text\n\n#reads_i\ncss .blog-footer-box \u003E span:last:text\nregS / / 1\n```"},{"id":"全分布模式","pId":"087db63","name":"全分布模式","parent":"安装","order":4,"sort_id":481205,"extname":".md","isParent":false,"isHidden":false,"content":"全分布模式需要在伪分布模式的基础上进行配置，您需要将不同的节点部署到不同的服务器上，并且在appSettings中指定ZooKeeper所在的服务器，假设我们需要在4台机器上部署RuiJi.Net集群(以A,B,C,D代表)，第一台机器部署所有代理节点(cp,ep,fp)及ZooKeeper服务，其他三台机器分别部署抓取(c)，抽取(e)及新闻源更新检测节点(f)\n1. A服务器的配置如下 假设A服务器IP为 192.168.101.10\n\n```\n{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    }\n  ]\n}\n```\n\n\u003E RuiJi.Net可以不使用自管理的ZooKeeper,这样您可以将ZooKeeper部署到任何服务器，只需为每个节点指明ZooKeeper服务器位置即可，您也可以把其中一个节点设置为使用自管理ZooKeeper,其他节点配置为使用自管理节点的ZooKeeper. 如果您的服务器具有多个IP地址，建议您将zkServer及nodeSettings下面所有的baseUrl更改为其中一个Ip地址，这样其他节点在设置ZooKeeper地址时会明确知道ZooKeeper服务器所在的地址。\n2. B服务器的配置如下\n```\n{\n  \"setting\": {\n    \"zkServer\": \"192.168.101.10:2181\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:36001\",\n      \"type\": \"c\",\n      \"proxy\": \"192.168.101.10:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:36002\",\n      \"type\": \"c\",\n      \"proxy\": \"192.168.101.10:36000\"\n    }\n  ]\n}\n```\n\n3. C服务器的配置如下\n```\n{\n  \"setting\": {\n    \"zkServer\": \"192.168.101.10:2181\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:37001\",\n      \"type\": \"e\",\n      \"proxy\": \"192.168.101.10:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37002\",\n      \"type\": \"e\",\n      \"proxy\": \"192.168.101.10:37000\"\n    }\n  ]\n}\n```\n4. D服务器的配置如下\n```\n{\n  \"setting\": {\n    \"zkServer\": \"192.168.101.10:2181\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:38001\",\n      \"type\": \"f\",\n      \"proxy\": \"192.168.101.10:38000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38002\",\n      \"type\": \"f\",\n      \"proxy\": \"192.168.101.10:38000\"\n    }\n  ]\n}\n```\n5. 确认所有服务器的防火墙开放相关端口\n6. 在所有机器上以管理员身份启动RuiJi.Net.Cmd.exe，进入任意控制台输出的管理网址，您将看到于伪分布模式同样的管理页面\n![](http://www.ruijihg.com/wp-content/uploads/2018/06/3-3.png)"},{"id":"3508e27","pId":0,"name":"抽取模型","parent":"","sort_id":482341,"order":4,"isParent":true,"extname":null,"open":true},{"id":"Tile","pId":"3508e27","name":"Tile","parent":"抽取模型","order":4,"sort_id":485650,"extname":".md","isParent":false,"isHidden":false,"content":"### Tile 抽取器\n\nTile为Block下重复的块，通常用来抽取列表类的源页面，Tile下的Selectors用来描述需要重复抽取的内容块, 通常Tile抽取器的选择结果是多个\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/3.png \"\")"},{"id":"规则","pId":"81b9a28","name":"规则","parent":"管理员UI/订阅源","order":4,"sort_id":497943,"extname":".md","isParent":false,"isHidden":false,"content":"### 规则\n通过规则选项卡，您可以对抓取页面规则进行添加、修改、查询等操作。\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/11.png)"},{"id":"URLFUNCTION","pId":"5356af4","name":"URLFUNCTION","parent":"管理员UI/设置","order":4,"sort_id":504420,"extname":".md","isParent":false,"isHidden":false,"content":"#### URLFUNCTION\n\nURLFUNCTION被用来处理Url地址，您可以这样在Url地址中使用函数\n\n```\nhttp://xxx.xxx.com.cn/roll.php?do=query\u0026callback=jsonp1475197217819\u0026_={# ticks() #}\u0026date={# now(\"yyyy-MM-dd\") #}\u0026size=20\u0026page={# page(1,2) #}\n```\n\n\u003E 在地址中使用函数，函数必须在{# #}中\n\nticks是一个生成时间戳的函数，now函数根据传入的格式按当前日期生成日期参数，page用来生成翻页，运行这个函数，您可能得到如下链接地址\n\n```\nhttp://xxx.xxx.com.cn/roll.php?do=query\u0026callback=jsonp1475197217819\u0026_=1475197217\u0026date=20180708\u0026size=20\u0026page=1\nhttp://xxx.xxx.com.cn/roll.php?do=query\u0026callback=jsonp1475197217819\u0026_=1475197217\u0026date=20180708\u0026size=20\u0026page=2\n```\n\npage 函数的定义如下\n\n```\nfor (int i = {0}; i \u003C= {1}; i++){{results.Add(i);}}\n```\n\n\u003E results是函数的输出结果，它是一个数组，您可以让您的函数返回多个数值，当地址具有多个函数时，RuiJi.Net 会按顺序计算它们的结果，每组结果或作为下一组函数计算的输入，假设您在地址中使用了两个地址函数，并且它们每个函数都返回两组结果，那么最终计算出的地址\n为2*2=4个\n\nRuiJi.Net 内置了几个函数, 源码如下\n\n##### ticks\n\n```\nresults.Add(DateTime.Now.Ticks);\n```\n示例: ticks()\n用途: 生成随机数\n\n##### page\n\n```\nfor (int i = {0}; i \u003C= {1}; i++){{results.Add(i);}}\n```\n\n示例: page(1,10)\n用途: 生成1到10页的地址\n\n##### limit\n\n```\nfor (int i = {0}; i \u003C= {1}; i++){{results.Add((i-1)*{2});}}\n```\n\n示例: limt(1,10,20)\n用途: 生成1到10页的地址，每页跨度20\n\n##### now\n\n```\nresults.Add(DateTime.Now.ToString(\"{0}\"));\n```\n\n示例: now(\"yyyy-MM-dd\")\n用途: 根据传入的格式按格式化当前日期"},{"id":"集群","pId":"5811dfb","name":"集群","parent":"管理员UI","order":4,"sort_id":497078,"extname":".md","isParent":false,"isHidden":false,"content":"集群选项卡显示了RuiJi.Net集群各个节点的运行状态，正常的节点以粗体表示，未启动或宕机的节点以正常字体表示。通过点击节点前面的圆圈，您可以跳转到相关节点的管理界面。\n\n\u003E 此选项卡在伪分布式、全分布式的模式可见\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/3-2.png)"},{"id":"节点类型及职责","pId":"087db63","name":"节点类型及职责","parent":"安装","order":5,"sort_id":481508,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net的节点分为6种，分别是抓取节点，抓取代理节点，抽取节点，抽取代理节点，新闻源监测节点，新闻源代理节点。\n\n各个节点的功能如下\n\n1. 抓取节点: 负责下载指定地址源文件\n2. 抓取代理节点: 负责维护可用抓取服务器列表及分配抓取任务\n3. 抽取节点: 根据规则进行抽取\n4. 抽取代理节点: 负责维护可用抽取服务器列表及分配抽取任务\n5. 订阅源监测节点: 负责定时检查订阅源更新，将更新地址转发给抓取节点下载并保存最后抽取结果\n6. 订阅源代理节点: 负责维护可用订阅源监测节点、记录及分配订阅源，根据地址匹配抽取规则\n\nRuiJi.Net 集群\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/05/2-2.png)"},{"id":"Meta","pId":"3508e27","name":"Meta","parent":"抽取模型","order":5,"sort_id":485660,"extname":".md","isParent":false,"isHidden":false,"content":"### Meta 抽取器\n\nMeta抽取器可以用在Tile和Block下，当Tile具有Meta时, Meta被用来抽取的Tile重复结果中需要抽取的元数据，通常被用来抽取列表信息。当Block具有Meta时，Meta用来提取Block中需要提取的元数据，通常用来提取详细页的元数据。\n\n##### 当Tile具有Meta时，Meta的抽取结果通常是多组\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/3-1.png \"\")\n\n##### 当Block具有Meta时，Meta的抽取结果通常为一组\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/4.png \"\")\n\n(~\u003E__\u003C~) 阅读为0"},{"id":"81b9a28","pId":"5811dfb","name":"订阅源","parent":"管理员UI","sort_id":497936,"order":5,"isParent":true,"extname":null,"open":true},{"id":"编辑规则","pId":"81b9a28","name":"编辑规则","parent":"管理员UI/订阅源","order":5,"sort_id":500992,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或规则的编辑按钮可进入规则详细编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/12.png)\n\n各字段属性对照表如下：\n\n|字段|描述|特性|\n| :-: | :-: | :-: |\n|Url|提取规则的原地址|支持关键词搜索，方便日后参考|\n|Expression|地址匹配表达式|支持关键词搜索,通配符*代表多个字符，?代表一个字符|\n|Method|请求方法|GET POST|\n|UA|浏览器User-Agent|为空则随机使用|\n|Hearders|请求标头|以回车分割|\n|Feature|界面特征|在一个界面有多重规则时，需根据界面特征进行规则选取|\n|Type|地址返回值格式|仅记录，无实际用途|\n|Ruiji Exp|Ruiji表达式|详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BB%8B%E7%BB%8D\u0026parent=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F\" target=\"blank\"\u003ERuiji表达式介绍\u003C/a\u003E|\n|Status|是否开启||\n|RunJs|是否执行页面JS|如果选择ON,RuiJi.Net将会使用无头浏览器对目标页面进行访问|"},{"id":"SELECTORPROCESSOR","pId":"5356af4","name":"SELECTORPROCESSOR","parent":"管理员UI/设置","order":5,"sort_id":504421,"extname":".md","isParent":false,"isHidden":false,"content":"#### SELECTORPROCESSOR\n\n函数选择器被用来在使用RuiJi.Net提供的标准选择器后，仍然不能满足抽取要求的场合，例如：我们经常在抓取日期的时候，取回的结果可能是时间戳或非完整的日期,也有可能遇到返回的是几分钟前或几天前，返回的结果并不是我们预期的结果，这时候可以使用SELECTORPROCESSOR来处理这样的结果。\n\n例如我们可以定义一个函数 名称为abc，内容如下\n\n```\nif (content.EndsWith(\"小时前\"))\n{{\n\tvar hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n\tresults.Add(DateTime.Now.AddHours(-hour));\n}}\n\nif (content.EndsWith(\"天前\"))\n{{\n\tvar hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n\tresults.Add(DateTime.Now.AddDays(-hour));\n}}\n\nif (content.EndsWith(\"AddMinutes\"))\n{{\n\tvar hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n\tresults.Add(DateTime.Now.AddDays(-hour));\n}}\n```\n\n\u003E 该代码是用C#实现的，如果您仅使用RuiJi.Net.Core的核心类库, 您需要将此代码以 函数名.pro 的形式存储于执行目录的funcs文件夹，如果您使用RuiJi.Net整个项目的进行管理的话，您还可以管理界面对函数选择器进行管理\n\n代码里面出现的content是当前的函数选择器上一个选择器的处理结果，通过自定义函数选择器，您可以根据您的抽取需求，对不精确的数据进行更精确的清洗。\n\n您可以在RuiJi表达式中，这样使用\n\n```\n[block]\n#BlockName\ncss #topsOfRecommend:ohtml\n\n[tile]\n#titlename\ncss .box-aw\n\n\t[meta]\n\t......\n\n\t#postdate\n\tcss .blog-footer-box \u003E span:eq(2):text\n\tproc abc\n```\n\n\n\u003E 我们在将来也会增加使用js实现的函数选择器"},{"id":"5da56ab","pId":0,"name":"选择器","parent":"","sort_id":485677,"order":5,"isParent":true,"extname":null,"open":true},{"id":"0f00588","pId":0,"name":"RuiJi表达式","parent":"","sort_id":482336,"order":6,"isParent":true,"extname":null,"open":true},{"id":"Paging抽取器","pId":"0f00588","name":"Paging抽取器","parent":"RuiJi表达式","order":6,"sort_id":490490,"extname":".md","isParent":false,"isHidden":false,"content":"Paging抽取器是一个特殊的抽取器，它被用来抽取页面的分页，Paging抽取器的抽取结果必须为链接地址，Paging选择器会自动按照链接出现的顺序抽取页面数据，并将[meta]中的content字段进行合并，Paging抽取器通常用于具有分页的详细页面。\n\n\n```\n[block]\n\n......\n\n[meta]\n......\n\n#content\ncss .a-con:ohtml\n\n[paging]\ncss .a-page\ncss a[href]\n```\n\n\u003E 您需要保证所抽取的页面为分页的第一页，否则分页的合并结果可能不正确"},{"id":"配置","pId":"087db63","name":"配置","parent":"安装","order":6,"sort_id":490057,"extname":".md","isParent":false,"isHidden":false,"content":"RuiJi.Net的配置文件如下,您需要在config文件中配置这些信息\n\n```\n{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\",\n    \"ruiJiServer\": \"localhost:36000\",\n    \"docServer\": \"localhost:80\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    },\n    {\n      \"baseUrl\": \"localhost:36001\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:36002\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37001\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37002\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38001\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38002\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    }\n  ]\n}\n```\n\n##### setting\n\n|名称|说明|\n| :-: | :-:  |\n|zkPath|zookeeper路径|\n|zkServer|zookeeper地址|\n|ruiJiServer|本地模式下服务地址|\n|docServer|文档服务器地址|\n\n\u003E zkPath 在使用自启动zookeeper时使用，您也可以不使用自管理的zookeeper\n\n##### appSettings\n\nRuiJi.Net可以使用自管理ZooKeeper 如果指定zkPath，RuiJi.Net将会自动启动ZooKeeper\n\nzkServer 被用来告诉所有的节点 ZooKeeper 服务器的位置"},{"id":"规则测试","pId":"81b9a28","name":"规则测试","parent":"管理员UI/订阅源","order":6,"sort_id":500993,"extname":".md","isParent":false,"isHidden":false,"content":"点击Test按钮可测试提取结果，如下图所示\n\n\u003E如果是伪分布式或全分布式模式，请先前往Setting \u003E Node设置好抓取节点可用IP\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/13.png)"},{"id":"5356af4","pId":"5811dfb","name":"设置","parent":"管理员UI","sort_id":497937,"order":6,"isParent":true,"extname":null,"open":true},{"id":"模拟用户代理","pId":"5356af4","name":"模拟用户代理","parent":"管理员UI/设置","order":6,"sort_id":504403,"extname":".md","isParent":false,"isHidden":false,"content":"Ruiji.Net在请求下载页面时会模拟用户代理（User Agent，以下简称UA），并根据UA设置使用Cookie管理器生成多个Cookie进行下载。Ruiji.Net对UA设置主要分为UA组设置及UA设置。UA组代表不同PC浏览器或手机浏览器，UA则是某个UA组下的不同UA。通过此设置界面您可以对UA组及下属UA进行增删改查。这里需要注意的是删除UA组的同时也会删除其所属所有UA。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/20.png)"},{"id":"无头浏览器","pId":"087db63","name":"无头浏览器","parent":"安装","order":7,"sort_id":580719,"extname":".md","isParent":false,"isHidden":false,"content":"如果您需要运行页面上的js脚本，您需要安装chromium无头浏览器。\n\n地址为 https://pan.baidu.com/s/1rsyCNnXxbobCBLZuPTiJHQ 访问密码 cr3e\n\n下载RuiJi.Net所部署的操作系统对应的chromium的zip包\n \n将运行文件解压至RuiJi.Net运行目录中的chromium文件夹中\n\n\u003E 如下图示例，是我发布的RuiJi.Net相对应的windows64位操作系统示例\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/28.png)\n\n\u003Elinux下需安装chromelib库\n\n``` linux\nyum install chromium-libs.x86_64\n```\n\n\u003E并给与chromium文件夹最高权限\n\n``` linux\nchmod -R 777 chromium\n```"},{"id":"b29e3c4","pId":0,"name":"深入了解RuiJi.Net","parent":"","sort_id":482335,"order":7,"isParent":true,"extname":null,"open":true},{"id":"编辑用户代理组","pId":"5356af4","name":"编辑用户代理组","parent":"管理员UI/设置","order":7,"sort_id":520273,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或者选择某个UA组后点击Update按钮，可进入UA组编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/21.png)"},{"id":"编辑用户代理","pId":"5356af4","name":"编辑用户代理","parent":"管理员UI/设置","order":8,"sort_id":520278,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或者点击某个UA的编辑按钮，可进入UA编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/22.png)\n\nDialog中各字段属性对照表如下\n\n|字段|描述|特性|\n| :-: | :-: | :-: |\n|Group|UA组名称||\n|Name|UA名称||\n|Value|UA具体值||\n|Count|生成Cookie数量|Ruiji.Net中的Cookie管理器会根据此值生成此数量的Cookie值\u003Cbr/\u003E以供使用此UA时进行Cookie轮询|"},{"id":"IP代理","pId":"5356af4","name":"IP代理","parent":"管理员UI/设置","order":9,"sort_id":504404,"extname":".md","isParent":false,"isHidden":false,"content":"Ruiji.Net在抓取的过程中，请求页面时，为防止被封，会采取多IP轮询制。IP代理设置可供请求页面时进行IP轮询。在此界面还可对代理进行及时测试。因代理不稳定，固每次测试结果可能不同。\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/23.png)\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/24.png)"},{"id":"编辑IP代理","pId":"5356af4","name":"编辑IP代理","parent":"管理员UI/设置","order":10,"sort_id":520376,"extname":".md","isParent":false,"isHidden":false,"content":"点击Add按钮或点击某个代理的编辑按钮，可进入代理编辑界面\n\n![](http://www.ruijihg.com/wp-content/uploads/2018/07/25.png)\n\nDialog中各字段属性对照表如下\n\n|字段|描述|特性|\n| :-: | :-: | :-: |\n|Ip|代理IP||\n|Port|端口||\n|UserName|代理登录账号||\n|Password|代理登录密码||\n|Type|代理类型|HTTP HTTPS|\n|Status|是否开启||\n"},{"id":"仓储","pId":"5356af4","name":"仓储","parent":"管理员UI/设置","order":11,"sort_id":520378,"extname":".md","isParent":false,"isHidden":false,"content":"日后我们会添加Storage设置，针对存储抓取结果，可设置使用不同数据库（例如MsSqlServer、Mysql、MongoDB、Solr等）进行存储。"},{"id":"插件","pId":"5356af4","name":"插件","parent":"管理员UI/设置","order":12,"sort_id":520379,"extname":".md","isParent":false,"isHidden":false,"content":".keep"}],"content":{"485777":"\u003Cp\u003ERuiJi表达式是为了快速添加抽取规则，实现规则与程序运行分离的一种方式，RuiJi表达式尽量的简单、易懂、配置灵活。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi表达式遵循RuiJi.Net的抽取模型，表达式所描述的抽取结构与RuiJi.Net的抽取模型一致。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi表达式可以存储于文本文件、数据库或高速缓存中，在需要进行抽取时再进行读取，这意味着您不需要重新启动程序，可以在任意需要的时刻更改表达式内容。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E在日后我们会让每一个抽取节点都可以缓存RuiJi表达式，并在需要时接收更改通知，对规则进行更新。\u003C/p\u003E\n\u003C/blockquote\u003E\n","416749":"\u003Cp\u003E\u003Cimg src=\"https://secure.gravatar.com/avatar/2d659788ba318c53b639092b4a4e27b8?s=100\u0026amp;r=g\u0026amp;d=retro\" /\u003E\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"介绍\" href=\"#介绍\"\u003E\u003C/a\u003E介绍\u003C/h3\u003E\u003Ch4\u003E\u003Ca class=\"anchor\" id=\"ruiji-net-是什么-\" href=\"#ruiji-net-是什么-\"\u003E\u003C/a\u003ERuiJi.Net 是什么?\u003C/h4\u003E\n\u003Chr\u003E\n\n\u003Cp\u003ERuiJi.Net是一个可以分布式部署的爬虫框架，使用C#编写，项目的最终目的是可以对大量的网站进行自动更新检查及抓取，使用者可以设置新闻源的检查时间间隔，在检测到新闻源更新后，会将更新的地址发送给下载节点，再由抽取节点对数据进行提取及清洗。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi.Net支持自管理Cookie,并且自动维护不同浏览器标识的Cookie，这意味着您可以在使用独立IP的基础上，虚拟出任意多的Cookie. RuiJi.Net同样支持使用抓取服务器上的IP进行轮询抓取，并且也可以使用代理服务器。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi.Net具有自己的抽取模型，称为RuiJi Expression（RuiJi表达式），您可以使用RuiJi表达式定义抽取模型，并对需要提取的元数据进行精确清洗。RuiJi表达式可以存储为文本文档、数据库及高速缓存中。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi.Net计划在将来提供PHP,JAVA等其他语言的SDK,以方便调用框架API.\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E该教程假设你已经具有一定的爬虫基础，且具有css,html,regex,xpath,json的处理经验，如果您刚开始接触爬虫，请先了解爬虫的基本知识，也许在将来，我们会准备些这方面的资料。\u003C/p\u003E\n\u003C/blockquote\u003E\n","481200":"\u003Cp\u003ERuiJi.Net有三种运行模式，分别为本地模式，伪分布模式，全分布模式。\u003C/p\u003E\n\n\u003Cp\u003E安装.net core 2.1环境\u003C/p\u003E\n\n\u003Cp\u003E您需要从github或gitee中获取源码，编译Ruiji.Net项目。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E您还可以通过网盘下载已编译好的项目，地址为 \u003Ca target=\"_blank\" href=\"https://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw\"\u003Ehttps://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw\u003C/a\u003E 访问密码 ef8d\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"如果您自行编译项目-请按如下操作进行\" href=\"#如果您自行编译项目-请按如下操作进行\"\u003E\u003C/a\u003E如果您自行编译项目，请按如下操作进行\u003C/h5\u003E\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E\u003Cp\u003E访问 \u003Ca target=\"_blank\" href=\"https://github.com/zhupingqi/RuiJi.Net\"\u003Ehttps://github.com/zhupingqi/RuiJi.Net\u003C/a\u003E 或 \u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net\"\u003Ehttps://gitee.com/zhupingqi/RuiJi.Net\u003C/a\u003E 下载Zip包，解压到您的目标文件夹\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003E使用 vs2017 打开项目，还原依赖包并编译项目。\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003E编译成功后使用 vs2017 发布项目。\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\n\u003Cp\u003E使用控制台进入发布文件夹，运行以下命令，启动项目\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Edotnet RuiJi.Net.Cmd.dll\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003C/li\u003E\n\u003C/ol\u003E\n","482337":"\u003Cp\u003ERuiJi.Net 将需抽取的目标进行了结构化处理，每一个需要抽取的目标页面被划分为以下结构 分别为 Block、Tile、Meta。这在RuiJi.Net中被称为抽取器。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/06/1-3.png\" /\u003E\u003C/p\u003E\n","416750":"\u003Cp\u003ERuiJi.Net 的设计目标是对大量的网站进行更新检查和快速抓取，抽取，清洗，这在最开始的介绍中已经提及。为了达到这个目标，RuiJi.Net将更新检查，下载，抽取清洗划分为不同的模块，这些模块分别运行在RuiJi.Net的不同节点上。RuiJi.Net的最终目标，是在全分布模式下，提供高可用性集群(HA)，以保障业务的连贯性。RuiJi.Net 可用用于舆情监测、企业新闻监测、自建搜索引擎等对实时要求教高的场景。\u003C/p\u003E\n\n\u003Cp\u003E以下为各个节点功能简介\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E抓取代理节点：维护抓取节点服务器列表，分配抓取任务\u003C/li\u003E\n\u003Cli\u003E抓取节点：负责下载指定地址源码\u003C/li\u003E\n\u003Cli\u003E抽取代理节点：维护抽取节点服务器列表，分配抽取任务\u003C/li\u003E\n\u003Cli\u003E抽取节点：根据规则对源码进行抽取，清洗\u003C/li\u003E\n\u003Cli\u003E新闻源代理节点：存储新闻源列表及规则列表，匹配提取规则\u003C/li\u003E\n\u003Cli\u003E新闻源节点：检查新闻源更新，请求抓取任务，转发抽取请求，保存抽取结果\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/05/2-2.png\" /\u003E\u003C/p\u003E\n","495933":"\u003Cp\u003ERuiJi.Net 提供基于Web的管理界面，管理界面地址为任意您在config中配置节点的baseUrl。通过管理界面，您可以观测到服务器的运行状态，日志，集群状态，并可以通过管理界面录入需要监测的订阅源地址，抽取规则。管理界面还提供了对抓取到的结果进行简单的预览，在设置选项卡中，您可以设置一些RuiJi.Net需要的参数。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/1.png\" /\u003E\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003ERuiJi.Net的管理界面中的选项卡分为两种类型，状态及日志显示的是当前节点的相关信息，集群、订阅源、抓取结果、设置从任意节点访问的结果是一样的，RuiJi.Net通过节点路由，将消息转发给相关节点进行处理。\u003C/p\u003E\n\u003C/blockquote\u003E\n","518401":"\u003Cp\u003E设置选项卡中的节点设置用来设置订阅源节点需要检查的订阅源范围以及抓取节点可以使用的IP范围。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E此选项卡在伪分布式、全分布式的模式可见\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"设置订阅源范围\" href=\"#设置订阅源范围\"\u003E\u003C/a\u003E设置订阅源范围\u003C/h3\u003E\n\u003Cp\u003E设置订阅源节点检测的订阅源范围，根据ID正序排列，每页取50条。例：节点Feed1输入设置1,3，那么节点Feed1在检查订阅源时，就会取出记录中的前50条及101条-150条，共100条订阅源去进行检查。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E多个节点不可重复检测同一页码\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"设置抓取节点ip范围\" href=\"#设置抓取节点ip范围\"\u003E\u003C/a\u003E设置抓取节点IP范围\u003C/h3\u003E\n\u003Cp\u003E设置抓取节点在抓取页面时可以使用的IP地址范围，在爬取数据时，会根据指定的IP进行IP轮询抓取。 \u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E请在第一次启动时务必为每个节点设置至少一个可用IP，如果无设置将无法正常下载任何内容\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/15.png\" /\u003E\u003C/p\u003E\n","485678":"\u003Cp\u003ERuiJi.Net 的选择器(Selector)被用来抽取所属结构的内容，通常为一个或多个，下一个选择器处理的是上一个选择器的处理结果，通过逐层处理的方式，我们可以将抽取结果进行精细化抽取，以达到最终需要的抽取结果。\u003C/p\u003E\n\n\u003Cp\u003ERuiJi.Net 的选择器有以下类型\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E类型\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003ECSS\u003C/td\u003E\n\u003Ctd\u003E样式选择器，类似于JQuery\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EREGEX\u003C/td\u003E\n\u003Ctd\u003E正则选择器\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EREGEXSPLIT\u003C/td\u003E\n\u003Ctd\u003E分割选择器，支持正则分割\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ETEXTRANGE\u003C/td\u003E\n\u003Ctd\u003E文本区域选择器\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEXCLUDE\u003C/td\u003E\n\u003Ctd\u003E排除选择器\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EREGEXREPLACE\u003C/td\u003E\n\u003Ctd\u003E替换选择器\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EJPATH\u003C/td\u003E\n\u003Ctd\u003EJSON选择器\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EXPATH\u003C/td\u003E\n\u003Ctd\u003Expath选择器，用来处理xml文档\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ECLEAR\u003C/td\u003E\n\u003Ctd\u003E清除选择器，清理html标签\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEXPRESSION\u003C/td\u003E\n\u003Ctd\u003E表达式选择器，用来匹配地址\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ESELECTORPROCESSOR\u003C/td\u003E\n\u003Ctd\u003E函数选择器，通过自定义函数处理选择器结果\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","485784":"\u003Cp\u003E如上所述，RuiJi表达式遵循RuiJi.Net的抽取结构，在RuiJi.Net中的抽取器包含Block、Tile、Meta, 在RuiJi表达式中使用[block]、[tile]、[meta]表示。\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"一个最简单的抽取表达式定义如下\" href=\"#一个最简单的抽取表达式定义如下\"\u003E\u003C/a\u003E一个最简单的抽取表达式定义如下\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[block]\n#recommend\ncss #topsOfRecommend\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E这个表达式定义了一个抽取器，抽取器的名称是recommend, 抽取器定义了一个css选择器，选择id为topsOfRecommend的outerHtml做为block抽取器的最终抽取内容。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E抽取器都可以包含名称，但对于block和tile来说，并不是必需的，如果需要定义抽取器的名称，则名称描述必须紧跟在抽取器之后（新行），并且以#开头。\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"具有tile的block\" href=\"#具有tile的block\"\u003E\u003C/a\u003E具有tile的block\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[block]\n#recommend\ncss #topsOfRecommend:ohtml\n\n[tile]\n#tile\ncss .box-aw\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E这里block的css选择器末尾加上了:ohtml，这与上一个示例一样，都是选择id为topsOfRecommend的outerHtml做为block抽取器的最终抽取内容。在这里第一个示例是简写，在选择结果为dom的情况下，如果没有指明选择后缀会默认使用outerHtml作为选择结果。可用后缀还包括html,text。\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E这里的tile抽取器抽取的内容是block抽取器的结果，也就是id为topsOfRecommend的outerHtml。在这个结果中选择样式为.box-aw的dom作为tile选择器的结果，这个结果为1个或多个。\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"继续在tile结果中抽取元数据\" href=\"#继续在tile结果中抽取元数据\"\u003E\u003C/a\u003E继续在tile结果中抽取元数据\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[block]\n#BlockName\ncss #topsOfRecommend:ohtml\n\n[tile]\n#titlename\ncss .box-aw\n\n    [meta]\n    #title\n    css .blog-title-link:[title]\n\n    #author\n    css .blog-footer-box \u0026gt; span:first:text\n\n    #postdate\n    css .blog-footer-box \u0026gt; span:eq(2):text\n\n    #reads_i\n    css .blog-footer-box \u0026gt; span:last:text\n    regS / / 1\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E这里的meta会向后缩进，以表示这个抽取器是tile的子抽取器，如果不缩进的话，则表示这个抽取器是block的抽取器。向后缩进的单位是一个制表符。\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003Emeta可以选择出多组数据，并且必须具有名称，每个需要抽取的元素之间需要一个空行。在本示例的中meta是处理tile的每一个抽取结果，meta的处理结果是一个字典。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E也许在未来我们会提供一个RuiJi表达式的编译器，以方便大家录入RuiJi表达式\u003C/p\u003E\n\u003C/blockquote\u003E\n","569215":"\u003Cp\u003E安装Linux .net core 2.1环境\u003C/p\u003E\n\n\u003Cp\u003E您需要从github或gitee中获取源码，编译Ruiji.Net项目。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E您还可以通过网盘下载已编译好的项目，地址为 \u003Ca target=\"_blank\" href=\"https://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw\"\u003Ehttps://pan.baidu.com/s/1xZFIGT1FF_toXzs42qPLUw\u003C/a\u003E 访问密码 ef8d\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"如果您自行编译项目-请按如下操作进行_1\" href=\"#如果您自行编译项目-请按如下操作进行_1\"\u003E\u003C/a\u003E如果您自行编译项目，请按如下操作进行\u003C/h5\u003E\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E\u003Cp\u003E访问 \u003Ca target=\"_blank\" href=\"https://github.com/zhupingqi/RuiJi.Net\"\u003Ehttps://github.com/zhupingqi/RuiJi.Net\u003C/a\u003E 或 \u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net\"\u003Ehttps://gitee.com/zhupingqi/RuiJi.Net\u003C/a\u003E 下载Zip包，解压到您的目标文件夹\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003E使用 vs2017 打开项目，还原依赖包并编译项目。\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003E编译成功后使用 vs2017 发布项目。\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003E将发布好的项目文件夹上传到Linux服务器\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\n\u003Cp\u003E进入Ruiji.Net目录，执行以下代码，启动项目\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Edotnet Ruiji.Net.Cmd.dll\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E您可以使用supervisord守护进程，使Ruiji.Net进入后台运行。\u003C/p\u003E\n\u003C/blockquote\u003E\n","496673":"\u003Cp\u003E状态选项卡显示当前节点的节点类型和状态。在这里您可以观测到如下内容。\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E节点类型,包括：STANDALONE,CRAWLER,CRAWLERPROXY,EXTRACTOR,EXTRACTORPROXY,FEED,FEEDPROXY\n\u0026gt; 在单机模式下，节点的类型为STANDALONE\u003C/li\u003E\n\u003Cli\u003E节点的启动时间\u003C/li\u003E\n\u003Cli\u003E节点运行的框架及服务器硬件环境\u003C/li\u003E\n\u003Cli\u003E节点所使用RuiJi.Net类库版本\u003C/li\u003E\n\u003Cli\u003E节点资源的消耗情况，包括：内存、CPU使用率，网卡\u003C/li\u003E\n\u003Cli\u003E作者近一月对项目的更新信息。\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/2-2.png\" /\u003E\u003C/p\u003E\n","497408":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"订阅源\" href=\"#订阅源\"\u003E\u003C/a\u003E订阅源\u003C/h3\u003E\n\u003Cp\u003E通过订阅源选项卡，您可以对需要抓取的订阅源进行添加、修改、查询等操作，并且可以直接进行规则测试，抓取模拟。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E在伪分布和全分布模式下，访问任一节点，您都可以对订阅源进行操作，并且这些操作都会被路由到订阅源代理节点进行处理\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/5.png\" /\u003E\n\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/6.png\" /\u003E\u003C/p\u003E\n","504402":"\u003Cp\u003ERuiJi.Net 中的函数可以被用来处理Url地址或选择器结果，函数分为两种类型：URLFUNCTION 和 SELECTORPROCESSOR\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/16.png\" /\u003E\u003C/p\u003E\n","485705":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"css-选择器\" href=\"#css-选择器\"\u003E\u003C/a\u003ECss 选择器\u003C/h3\u003E\n\u003Cp\u003Ecss选择器使用的类库是CsQuery, CsQuery提供了类似JQuery的方法，通过css选择器来处理html页面。在RuiJi.Net中通常css选择器会作为Selectors的第一个选择器，用来定位选择区域。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"regex-选择器\" href=\"#regex-选择器\"\u003E\u003C/a\u003ERegex 选择器\u003C/h3\u003E\n\u003Cp\u003Eregex选择器是使用正则表达式来抽取内容，在RuiJi.Net可以通过配置提取表达式结果或分组结果。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"regexsplit-选择器\" href=\"#regexsplit-选择器\"\u003E\u003C/a\u003ERegexSplit 选择器\u003C/h3\u003E\n\u003Cp\u003E以正则表达式分割字符串，并提取其中的指定索引的结果，可以指定多个\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"textrange-选择器\" href=\"#textrange-选择器\"\u003E\u003C/a\u003ETextRange 选择器\u003C/h3\u003E\n\u003Cp\u003E文本区域选择器，该选择器通过定义文本开始的字符串和文本结束的字符串，来抽取开始和结束文本区域中间的内容。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"exclude-选择器\" href=\"#exclude-选择器\"\u003E\u003C/a\u003EExclude 选择器\u003C/h3\u003E\n\u003Cp\u003E排除选择器用来排除指定的文本内容。需排除的内容以正则表达式定义。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"regexreplace-选择器\" href=\"#regexreplace-选择器\"\u003E\u003C/a\u003ERegexReplace 选择器\u003C/h3\u003E\n\u003Cp\u003E正则替换选择器，被用来将匹配出的结果替换成目标结果。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"jpath-选择器\" href=\"#jpath-选择器\"\u003E\u003C/a\u003EJPath 选择器\u003C/h3\u003E\n\u003Cp\u003EJsonPath 选择器被用来处理Json格式的文档。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"xpath-选择器\" href=\"#xpath-选择器\"\u003E\u003C/a\u003EXPath 选择器\u003C/h3\u003E\n\u003Cp\u003EXPath 选择器被用来处理XML文档\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"clear-选择器\" href=\"#clear-选择器\"\u003E\u003C/a\u003EClear 选择器\u003C/h3\u003E\n\u003Cp\u003EClear选择器会自动清除一些Html源文件的标签，包含:script、style、iframe、input、textarea、select、form及注释等。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"expression-选择器\" href=\"#expression-选择器\"\u003E\u003C/a\u003EExpression 选择器\u003C/h3\u003E\n\u003Cp\u003E表达式选择器通常使用通配符抽取需要的链接地址。\u003C/p\u003E\n\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"selectorprocessor-选择器\" href=\"#selectorprocessor-选择器\"\u003E\u003C/a\u003ESELECTORPROCESSOR 选择器\u003C/h3\u003E\n\u003Cp\u003ESELECTORPROCESSOR 选择允许用户调用外部已经定义好的函数处理一些特殊的抽取结果，例如抽取出的时间是 xx 分钟前。\u003C/p\u003E\n","485813":"\u003Cp\u003E这里我们以抽取出栏目名称为例，假设一个页面的栏目的源码如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u0026lt;td\u0026gt;\n    \u0026lt;div style=\"width:616px; float:left;\" class=\"f12 black\"\u0026gt;\n     \u0026lt;ul style=\"margin:0; padding:0;\"\u0026gt;\n      \u0026lt;li style=\"float:left; width:120px; text-align:right;\"\u0026gt;法制网首页\u0026amp;gt;\u0026amp;gt;\u0026lt;/li\u0026gt;\n      \u0026lt;li style=\"float:left; width:350px; text-align:left;\"\u0026gt;\n              \u0026lt;span style=\"padding:5px 0px 5px 15px;\"\u0026gt;\n            \u0026lt;a href=\"../../../node_34228.htm\" target=\"_blank\" class=\"f12 black\"\u0026gt;评论频道\u0026lt;/a\u0026gt;\n                \u0026lt;font class=\"f12 black\"\u0026gt;\u0026amp;gt;\u0026amp;gt;\u0026lt;/font\u0026gt;\n                \u0026lt;a href=\"../../../node_34252.htm\" target=\"_blank\" class=\"f12 black\"\u0026gt;法治时评\u0026lt;/a\u0026gt;\n          \u0026lt;/span\u0026gt;\n            \u0026lt;/li\u0026gt;\n     \u0026lt;/ul\u0026gt;\n    \u0026lt;/div\u0026gt;\n\u0026lt;/td\u0026gt;\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E我们使用如下的RuiJi表达式对栏目进行抽取，同时需要去除 法制网首页\u0026gt;\u0026gt; 的文本，那么选择器定义可以如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[meta]\n#railling\ncss div.f12:text\nex /\\s+法制网首页\u0026gt;\u0026gt;/ -b\nregR /\u0026gt;\u0026gt;/ \u0026gt;\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E在这里第一个选择器首先选择出div.f12的文本，结果如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E 法制网首页\u0026gt;\u0026gt; 评论频道\u0026gt;\u0026gt;法治时评\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E然后使用排除选择器在文本开始部分排除掉 法制网首页\u0026gt;\u0026gt; （-b是排除开始文本的意思） 得到结果如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E 评论频道\u0026gt;\u0026gt;法治时评\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E再次我们需要将 \u0026gt;\u0026gt; 替换为 \u0026gt; 最终结果如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E评论频道\u0026gt;法治时评\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E当然我们也可以这样去抽取栏目\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[meta]\n#railling\ncss div.f12 span:text\nregR /\u0026gt;\u0026gt;/ \u0026gt;\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E这与上面的结果是一致的。\u003C/p\u003E\n","416748":"\u003Ch4\u003E\u003Ca class=\"anchor\" id=\"本地模式\" href=\"#本地模式\"\u003E\u003C/a\u003E本地模式\u003C/h4\u003E\n\u003Cp\u003ERuiJi.Net的本地模式常用于演示效果和测试\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E首先确保 运行目录下具有 ruiji.json 配置文件\u003C/li\u003E\n\u003Cli\u003Eruiji.json 的配置如下（如果您没有修改过的话，这些配置是默认的）\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E{\n  \"setting\": {\n    \"ruiJiServer\": \"localhost:36000\",\n    \"docServer\": \"localhost:80\"\n  },\n  \"nodes\": [\n  ]\n}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cul class=\"task-list\"\u003E\n\u003Cli\u003EruiJiServer 是RuiJi.Net的管理员页面地址\u003C/li\u003E\n\u003Cli\u003EdocServer 是RuiJi.Net的帮助文档页面，如果不需要，您可以注释掉这部分\u003C/li\u003E\n\u003C/ul\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E运行 dotnet RuiJi.Net.Cmd.dll \u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cp\u003E如果您看到如下信息，恭喜您，启动成功\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003EHosting environment: Production\n......\nNow listening on: http://192.168.31.32:80\nApplication started. Press Ctrl+C to shut down.\nHosting environment: Production\n......\nNow listening on: http://192.168.31.32:36000\nApplication started. Press Ctrl+C to shut down.\n2018-07-29 11:19:52,015 [1] INFO  - 192.168.31.32:36000 feed scheduler starting\n2018-07-29 11:19:52,030 [1] INFO  - 192.168.31.32:36000 feed scheduler started\n2018-07-29 11:19:52,033 [1] INFO  - Start WebApiServer At http://192.168.31.32:36000 with STANDALONE node\n......\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E在浏览器中输入控制台中提示的地址，以上为例的话，输入 \u003Ca target=\"_blank\" href=\"http://192.168.31.32:36000\"\u003Ehttp://192.168.31.32:36000\u003C/a\u003E\n您将看到类似如下的管理页面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/06/4-3.png\" /\u003E\u003C/p\u003E\n","482347":"\u003Cp\u003E每一个RuiJi.Net的抽取器都包含Selectors, Selectors是被用来定义所属抽取器需抽取内容的选择器。Selectors是由Selector组成，每个Selector都依赖上一个Selector的处理结果，也就是下一个Selecor相对与上一个Selector会抽取更精细的内容. \u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如果所属抽取器没有定义Selectors，抽取器的抽取内容会被默认为返回整个文档内容或父抽取器的抽取结果。\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/2.png\" /\u003E\u003C/p\u003E\n","497181":"\u003Cp\u003E日志选项卡显示了当前节点的日志，包括节点启动日志，任务调度信息及抓取，抽取日志。日志选项卡的日志最多只显示最近1000条，如果您需要查看更多的日志，请在对应节点的运行目录下的logs文件夹里面查看。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/4-1.png\" /\u003E\u003C/p\u003E\n","500986":"\u003Cp\u003E点击Add按钮或订阅源的编辑按钮，可进入订阅源详细编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/27.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003E在Address中，您可以填写地址函数，以{# #}包裹。您将在以后的章节中看到地址函数的介绍。图中所示函数的功能为，每次扫描订阅源的前两页。\u003C/p\u003E\n\n\u003Cp\u003E请求方法为POST时需设置Content-Type及Data参数。\u003C/p\u003E\n\n\u003Cp\u003EDialog中各字段属性对照表如下\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E字段\u003C/th\u003E\n\u003Cth\u003E描述\u003C/th\u003E\n\u003Cth\u003E特性\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003ESite name\u003C/td\u003E\n\u003Ctd\u003E订阅源站点名称\u003C/td\u003E\n\u003Ctd\u003E支持关键词搜索\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ERemark\u003C/td\u003E\n\u003Ctd\u003E备注信息\u003C/td\u003E\n\u003Ctd\u003E支持关键词搜索\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EAddress\u003C/td\u003E\n\u003Ctd\u003E地址链接\u003C/td\u003E\n\u003Ctd\u003E支持关键词搜索\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EMethod\u003C/td\u003E\n\u003Ctd\u003E请求方法\u003C/td\u003E\n\u003Ctd\u003EGET POST\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EContent-Type\u003C/td\u003E\n\u003Ctd\u003E内容类型\u003C/td\u003E\n\u003Ctd\u003Eapplication/x-www-form-urlencoded\u003Cbr\u003Eapplication/json\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EData\u003C/td\u003E\n\u003Ctd\u003E请求参数\u003C/td\u003E\n\u003Ctd\u003E根据内容类型设置不同格式的请求参数\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EUA\u003C/td\u003E\n\u003Ctd\u003E浏览器User-Agent\u003C/td\u003E\n\u003Ctd\u003E为空则随机使用Setting中设置的UA\u003Cbr\u003E如果Setting中无UA设置则默认使用Ruiji自带\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EHearders\u003C/td\u003E\n\u003Ctd\u003E请求标头\u003C/td\u003E\n\u003Ctd\u003E以回车分割\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EGenre\u003C/td\u003E\n\u003Ctd\u003E订阅源类型\u003C/td\u003E\n\u003Ctd\u003E方便日后进行订阅源分类\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EType\u003C/td\u003E\n\u003Ctd\u003E地址返回值格式\u003C/td\u003E\n\u003Ctd\u003E仅记录，无实际用途\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ERuiJi Exp\u003C/td\u003E\n\u003Ctd\u003ERuiji表达式\u003C/td\u003E\n\u003Ctd\u003E详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BB%8B%E7%BB%8D\u0026amp;parent=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F\" target=\"blank\"\u003ERuiji表达式介绍\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EDelay\u003C/td\u003E\n\u003Ctd\u003E延迟执行时间\u003C/td\u003E\n\u003Ctd\u003E订阅源更新后延迟多久开始下载目标链接\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EScheduling\u003C/td\u003E\n\u003Ctd\u003E扫描时间间隔\u003C/td\u003E\n\u003Ctd\u003ECron表达式\u003Cbr\u003E可选择选项自动生成也可填写\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EStatus\u003C/td\u003E\n\u003Ctd\u003E是否开启\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ERunJs\u003C/td\u003E\n\u003Ctd\u003E是否执行页面JS\u003C/td\u003E\n\u003Ctd\u003E如果选择ON,\u003Cbr\u003ERuiJi.Net将会使用无头浏览器对目标页面进行访问\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EWaitDom\u003C/td\u003E\n\u003Ctd\u003E执行页面JS时等待某个Dom元素\u003C/td\u003E\n\u003Ctd\u003Ecss selector形式\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","518882":"\u003Cp\u003E点击Add按钮或函数的编辑按钮，可进入函数编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/17.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003EDialog中各字段属性对照表如下\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E字段\u003C/th\u003E\n\u003Cth\u003E描述\u003C/th\u003E\n\u003Cth\u003E特性\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EName\u003C/td\u003E\n\u003Ctd\u003E函数名称\u003C/td\u003E\n\u003Ctd\u003E以供调用时使用\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ECode\u003C/td\u003E\n\u003Ctd\u003E具体执行代码\u003C/td\u003E\n\u003Ctd\u003E暂时只支持C#代码编写\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EType\u003C/td\u003E\n\u003Ctd\u003E函数类型\u003C/td\u003E\n\u003Ctd\u003E详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=URLFUNCTION\u0026amp;parent=%E7%AE%A1%E7%90%86%E5%91%98UI%2F%E8%AE%BE%E7%BD%AE\" target=\"_blank\"\u003EURLFUNCTION\u003C/a\u003E和\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=SELECTORPROCESSOR\u0026amp;parent=%E7%AE%A1%E7%90%86%E5%91%98UI%2F%E8%AE%BE%E7%BD%AE\" target=\"_blank\"\u003ESELECTORPROCESSOR\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ESmaple\u003C/td\u003E\n\u003Ctd\u003E使用示例\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","485823":"\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"css-选择器_1\" href=\"#css-选择器_1\"\u003E\u003C/a\u003ECss 选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Ecss tag:[xxx]\u003C/td\u003E\n\u003Ctd\u003E选择属性\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Ecss tag:text\u003C/td\u003E\n\u003Ctd\u003E选择文本\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Ecss tag:ohtml\u003C/td\u003E\n\u003Ctd\u003E选择outerHtml\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Ecss tag:html\u003C/td\u003E\n\u003Ctd\u003E选择innerHtml\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Ecss dd:[class=’f12 balck02 yh’] + dd:text\u003C/td\u003E\n\u003Ctd\u003E选择tag为dd,class为‘f12 balck01 yh’紧邻的dd的文本\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"exclude-排除选择器\" href=\"#exclude-排除选择器\"\u003E\u003C/a\u003EExclude 排除选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Eex /abc/ -b\u003C/td\u003E\n\u003Ctd\u003E在文本开始排除\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eex /abc/ -a\u003C/td\u003E\n\u003Ctd\u003E在文本任意位置排除\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eex /abc/ -e\u003C/td\u003E\n\u003Ctd\u003E在文本结尾排除\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E/abc/为正则表达式,以下以/开头再以/结尾的字符串均表示正则\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"expresssion-通配符选择器-仅适用于网址提取-\" href=\"#expresssion-通配符选择器-仅适用于网址提取-\"\u003E\u003C/a\u003EExpresssion 通配符选择器（仅适用于网址提取）\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Eexp \u003Ca target=\"_blank\" href=\"http://www.ruijihg.com/*\"\u003Ehttp://www.ruijihg.com/*\u003C/a\u003E\u003C/td\u003E\n\u003Ctd\u003E使用通配符匹配任何以\u003Ca target=\"_blank\" href=\"http://www.ruijihg.com/开头的网址\"\u003Ehttp://www.ruijihg.com/开头的网址\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eexp \u003Ca target=\"_blank\" href=\"http://www.ruijihg.com/\"\u003Ehttp://www.ruijihg.com/\u003C/a\u003E???\u003C/td\u003E\n\u003Ctd\u003E使用通配符匹配以\u003Ca target=\"_blank\" href=\"http://www.ruijihg.com/开头，后面跟3个字符的网址\"\u003Ehttp://www.ruijihg.com/开头，后面跟3个字符的网址\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"regex-正则选择器\" href=\"#regex-正则选择器\"\u003E\u003C/a\u003ERegex 正则选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Ereg /abc/\u003C/td\u003E\n\u003Ctd\u003E匹配正则结果\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Ereg /abc(.*)/ 1\u003C/td\u003E\n\u003Ctd\u003E匹配正则分组结果 取出第n个结果\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"regexsplit-分割选择器\" href=\"#regexsplit-分割选择器\"\u003E\u003C/a\u003ERegexSplit 分割选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EregS /abc/ 3\u003C/td\u003E\n\u003Ctd\u003E以正则分割字符串 取出第n个结果\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"regexreplace-替换选择器\" href=\"#regexreplace-替换选择器\"\u003E\u003C/a\u003ERegexReplace 替换选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EregR /abc/ 123\u003C/td\u003E\n\u003Ctd\u003E替换匹配出的正则结果\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"textrange-文本区域选择器\" href=\"#textrange-文本区域选择器\"\u003E\u003C/a\u003ETextRange 文本区域选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Etext /abc/ /edf/\u003C/td\u003E\n\u003Ctd\u003E取出以/abc/开头，/edf/结尾中的字符串\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"xpath-选择器_1\" href=\"#xpath-选择器_1\"\u003E\u003C/a\u003EXPath 选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Expath /bookstore/book[1]\u003C/td\u003E\n\u003Ctd\u003Expath\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"jsonpath-选择器\" href=\"#jsonpath-选择器\"\u003E\u003C/a\u003EJsonPath 选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Ejpath $..url\u003C/td\u003E\n\u003Ctd\u003Ejsonpath\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"selectorprocessor-选择器_1\" href=\"#selectorprocessor-选择器_1\"\u003E\u003C/a\u003ESELECTORPROCESSOR 选择器\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E表达式\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003Eproc name\u003C/td\u003E\n\u003Ctd\u003E执行名称为name的函数\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","481199":"\u003Cp\u003E伪分布模式需要使用zookeeper,首先安装如下步骤安装zookeeper\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E访问 \u003Ca target=\"_blank\" href=\"http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/\"\u003Ehttp://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E下载ZooKeeper压缩包，并解压到RuiJi.Net的运行目录\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如果需要更改zookeeper的数据目录，请修改zookeeper下/conf/zoo.cfg dataDir\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E# The number of milliseconds of each tick\ntickTime=2000\n# The number of ticks that the initial \n# synchronization phase can take\ninitLimit=10\n# The number of ticks that can pass between \n# sending a request and getting an acknowledgement\nsyncLimit=5\n# the directory where the snapshot is stored.\n# do not use /tmp for storage, /tmp here is just \n# example sakes.\ndataDir=e:\\\\zookeeper\\\\data\n#dataLogDir=e:\\\\zookeeper\\\\log\n# the port at which the clients will connect\nclientPort=2181\n#\n# Be sure to read the maintenance section of the \n# administrator guide before turning on autopurge.\n#\n# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance\n#\n# The number of snapshots to retain in dataDir\n#autopurge.snapRetainCount=3\n# Purge task interval in hours\n# Set to \"0\" to disable auto purge feature\n#autopurge.purgeInterval=1\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E在ruiji.json里面增加zkPath如下,其中value为ZooKeeper在RuiJi.Net运行目录下的文件夹名称，如果以前配置过本地模式，可以把ruiJiServer注释掉\u003C/li\u003E\n\u003Cli\u003E在nodes节点下增加如下配置\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\" \n  },\n  \"nodes\": [\n     {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    },\n    {\n      \"baseUrl\": \"localhost:36001\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:36002\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37001\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37002\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38001\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38002\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    }\n  ]\n}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E启动RuiJi.Net，您将看到很多的输出日志，程序会首先会启动ZooKeeper, 然后按照配置文件，逐个启动对应的节点。\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Exxxx Start WebApiServer At http://192.168.31.196:37000 with ExtractorPROXY node\n......\nxxxx Start WebApiServer At http://192.168.31.196:36001 with CRAWLER node\n......\nplease e to exit!\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E如果您看到以上信息的最后一条，那么您就可以打开浏览器，输入任何在控制台中输出的节点网址，访问RuiJi.Net的管理网站\u003C/p\u003E\n\n\u003Cp\u003E在伪分布和全分布的模式下，管理网站的导航菜单会出现节点和集群的选项卡\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/06/3-3.png\" /\u003E\u003C/p\u003E\n","482340":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"block-抽取器\" href=\"#block-抽取器\"\u003E\u003C/a\u003EBlock 抽取器\u003C/h3\u003E\n\u003Cp\u003EBlock为RuiJi.Net抽取模型中最基础的单位，Block负责定位抽取区域，Block下的Tile和Meta会在Block抽取结果中进行抽取，Block下的Selectors为Block抽取器的选择器。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/bb647a1f149e9887c5858c1f90725945a53.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003EBlock抽取器下面还可以再包含多个Block,在Block中以Blocks表示。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E使用Block定位抽取区域的原因是源页面可能包含多个重复区域，而我们只对其中的部分感兴趣，这样我们可以仅对感兴趣的区域进行抽取，忽略其他的区域。如上所示，也许我们只对最新推荐感兴趣，而其他的今日热门，本周热门等我们不需要进行抽取。\u003C/p\u003E\n\u003C/blockquote\u003E\n","497064":"\u003Cp\u003E节点选项卡用来展示ZooKeeper中的内容，包括ZooKeeper的树形结构，ZooKeeper各个路径上保存的信息。您也可以在这里查看设置的抓取节点可以使用的IP范围，及Feed节点需要检查的订阅源范围。这两项设置您可以在设置选卡的Node下进行设置。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E此选项卡在伪分布式、全分布式的模式可见\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/26.png\" /\u003E\u003C/p\u003E\n","500989":"\u003Cp\u003EDialog中的Test按钮可以测试您的RuiJi表达式的抽取结果, 如下图所示\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如果是伪分布式或全分布式模式，请先前往Setting \u0026gt; Node设置好抓取节点可用IP\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/9.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003EDownload Target可下载目标地址，并以对应的格式保存于服务器上，如下图所示\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/10.png\" /\u003E\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003ERuiJi.Net通过固定时间间隔，访问订阅源，并通过算法检查订阅源的更新链接地址，订阅源的选择结果必须为链接地址，如果您不这么做的话，RuiJi.Net在下载完订阅源之后，将不会做任何操作。\u003C/p\u003E\n\u003C/blockquote\u003E\n","520174":"\u003Cp\u003E点击Test按钮，可根据您的使用示例测试函数结果。如下图所示\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/19.png\" /\u003E\u003C/p\u003E\n","485826":"\u003Cp\u003ERuiJi.Net 的抽取器可以将选择器处理结果转换为目标数据类型，类型转换是透过在抽取器名称后加后缀完成的，以下列表为抽取器名称可用后缀及其转换类型\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E后缀\u003C/th\u003E\n\u003Cth\u003E目标转换类型\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003E*_i\u003C/td\u003E\n\u003Ctd\u003Eint\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_s\u003C/td\u003E\n\u003Ctd\u003Estring\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_l\u003C/td\u003E\n\u003Ctd\u003Elong\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_b\u003C/td\u003E\n\u003Ctd\u003Ebool\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_f\u003C/td\u003E\n\u003Ctd\u003Efloat\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_d\u003C/td\u003E\n\u003Ctd\u003Edouble\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E*_dt\u003C/td\u003E\n\u003Ctd\u003Edatetime\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如果不指定后缀，抽取器会默认返回字符串类型，如果转换发生异常，抽取器同样会返回字符串类型\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E以下为一个简单的示例\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[meta]\n#title\ncss .blog-title-link:[title]\n\n#author\ncss .blog-footer-box \u0026gt; span:first:text\n\n#postdate_dt\ncss .blog-footer-box \u0026gt; span:eq(2):text\n\n#reads_i\ncss .blog-footer-box \u0026gt; span:last:text\nregS / / 1\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E","481205":"\u003Cp\u003E全分布模式需要在伪分布模式的基础上进行配置，您需要将不同的节点部署到不同的服务器上，并且在appSettings中指定ZooKeeper所在的服务器，假设我们需要在4台机器上部署RuiJi.Net集群(以A,B,C,D代表)，第一台机器部署所有代理节点(cp,ep,fp)及ZooKeeper服务，其他三台机器分别部署抓取(c)，抽取(e)及新闻源更新检测节点(f)\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003EA服务器的配置如下 假设A服务器IP为 192.168.101.10\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    }\n  ]\n}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003ERuiJi.Net可以不使用自管理的ZooKeeper,这样您可以将ZooKeeper部署到任何服务器，只需为每个节点指明ZooKeeper服务器位置即可，您也可以把其中一个节点设置为使用自管理ZooKeeper,其他节点配置为使用自管理节点的ZooKeeper. 如果您的服务器具有多个IP地址，建议您将zkServer及nodeSettings下面所有的baseUrl更改为其中一个Ip地址，这样其他节点在设置ZooKeeper地址时会明确知道ZooKeeper服务器所在的地址。\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003EB服务器的配置如下\n\u003Ccode\u003E\n{\n\u0026quot;setting\u0026quot;: {\n\u0026quot;zkServer\u0026quot;: \u0026quot;192.168.101.10:2181\u0026quot;\n},\n\u0026quot;nodes\u0026quot;: [\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:36001\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;c\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:36000\u0026quot;\n},\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:36002\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;c\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:36000\u0026quot;\n}\n]\n}\n\u003C/code\u003E\u003C/li\u003E\n\u003C/ol\u003E\n\u003C/blockquote\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003EC服务器的配置如下\n\u003Ccode\u003E\n{\n\u0026quot;setting\u0026quot;: {\n\u0026quot;zkServer\u0026quot;: \u0026quot;192.168.101.10:2181\u0026quot;\n},\n\u0026quot;nodes\u0026quot;: [\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:37001\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;e\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:37000\u0026quot;\n},\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:37002\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;e\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:37000\u0026quot;\n}\n]\n}\n\u003C/code\u003E\u003C/li\u003E\n\u003Cli\u003ED服务器的配置如下\n\u003Ccode\u003E\n{\n\u0026quot;setting\u0026quot;: {\n\u0026quot;zkServer\u0026quot;: \u0026quot;192.168.101.10:2181\u0026quot;\n},\n\u0026quot;nodes\u0026quot;: [\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:38001\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;f\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:38000\u0026quot;\n},\n{\n  \u0026quot;baseUrl\u0026quot;: \u0026quot;localhost:38002\u0026quot;,\n  \u0026quot;type\u0026quot;: \u0026quot;f\u0026quot;,\n  \u0026quot;proxy\u0026quot;: \u0026quot;192.168.101.10:38000\u0026quot;\n}\n]\n}\n\u003C/code\u003E\u003C/li\u003E\n\u003Cli\u003E确认所有服务器的防火墙开放相关端口\u003C/li\u003E\n\u003Cli\u003E在所有机器上以管理员身份启动RuiJi.Net.Cmd.exe，进入任意控制台输出的管理网址，您将看到于伪分布模式同样的管理页面\n\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/06/3-3.png\" /\u003E\u003C/li\u003E\n\u003C/ol\u003E\n","485650":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"tile-抽取器\" href=\"#tile-抽取器\"\u003E\u003C/a\u003ETile 抽取器\u003C/h3\u003E\n\u003Cp\u003ETile为Block下重复的块，通常用来抽取列表类的源页面，Tile下的Selectors用来描述需要重复抽取的内容块, 通常Tile抽取器的选择结果是多个\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/3.png\" /\u003E\u003C/p\u003E\n","497943":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"规则\" href=\"#规则\"\u003E\u003C/a\u003E规则\u003C/h3\u003E\n\u003Cp\u003E通过规则选项卡，您可以对抓取页面规则进行添加、修改、查询等操作。\n\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/11.png\" /\u003E\u003C/p\u003E\n","504420":"\u003Ch4\u003E\u003Ca class=\"anchor\" id=\"urlfunction\" href=\"#urlfunction\"\u003E\u003C/a\u003EURLFUNCTION\u003C/h4\u003E\n\u003Cp\u003EURLFUNCTION被用来处理Url地址，您可以这样在Url地址中使用函数\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Ehttp://xxx.xxx.com.cn/roll.php?do=query\u0026amp;callback=jsonp1475197217819\u0026amp;_={# ticks() #}\u0026amp;date={# now(\"yyyy-MM-dd\") #}\u0026amp;size=20\u0026amp;page={# page(1,2) #}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E在地址中使用函数，函数必须在{# #}中\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003Eticks是一个生成时间戳的函数，now函数根据传入的格式按当前日期生成日期参数，page用来生成翻页，运行这个函数，您可能得到如下链接地址\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Ehttp://xxx.xxx.com.cn/roll.php?do=query\u0026amp;callback=jsonp1475197217819\u0026amp;_=1475197217\u0026amp;date=20180708\u0026amp;size=20\u0026amp;page=1\nhttp://xxx.xxx.com.cn/roll.php?do=query\u0026amp;callback=jsonp1475197217819\u0026amp;_=1475197217\u0026amp;date=20180708\u0026amp;size=20\u0026amp;page=2\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003Epage 函数的定义如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Efor (int i = {0}; i \u0026lt;= {1}; i++){{results.Add(i);}}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003Eresults是函数的输出结果，它是一个数组，您可以让您的函数返回多个数值，当地址具有多个函数时，RuiJi.Net 会按顺序计算它们的结果，每组结果或作为下一组函数计算的输入，假设您在地址中使用了两个地址函数，并且它们每个函数都返回两组结果，那么最终计算出的地址\n为2*2=4个\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003ERuiJi.Net 内置了几个函数, 源码如下\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"ticks\" href=\"#ticks\"\u003E\u003C/a\u003Eticks\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eresults.Add(DateTime.Now.Ticks);\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E示例: ticks()\n用途: 生成随机数\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"page\" href=\"#page\"\u003E\u003C/a\u003Epage\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Efor (int i = {0}; i \u0026lt;= {1}; i++){{results.Add(i);}}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E示例: page(1,10)\n用途: 生成1到10页的地址\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"limit\" href=\"#limit\"\u003E\u003C/a\u003Elimit\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Efor (int i = {0}; i \u0026lt;= {1}; i++){{results.Add((i-1)*{2});}}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E示例: limt(1,10,20)\n用途: 生成1到10页的地址，每页跨度20\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"now\" href=\"#now\"\u003E\u003C/a\u003Enow\u003C/h5\u003E\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eresults.Add(DateTime.Now.ToString(\"{0}\"));\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cp\u003E示例: now(\"yyyy-MM-dd\")\n用途: 根据传入的格式按格式化当前日期\u003C/p\u003E\n","497078":"\u003Cp\u003E集群选项卡显示了RuiJi.Net集群各个节点的运行状态，正常的节点以粗体表示，未启动或宕机的节点以正常字体表示。通过点击节点前面的圆圈，您可以跳转到相关节点的管理界面。\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E此选项卡在伪分布式、全分布式的模式可见\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/3-2.png\" /\u003E\u003C/p\u003E\n","481508":"\u003Cp\u003ERuiJi.Net的节点分为6种，分别是抓取节点，抓取代理节点，抽取节点，抽取代理节点，新闻源监测节点，新闻源代理节点。\u003C/p\u003E\n\n\u003Cp\u003E各个节点的功能如下\u003C/p\u003E\n\n\u003Col class=\"task-list\"\u003E\n\u003Cli\u003E抓取节点: 负责下载指定地址源文件\u003C/li\u003E\n\u003Cli\u003E抓取代理节点: 负责维护可用抓取服务器列表及分配抓取任务\u003C/li\u003E\n\u003Cli\u003E抽取节点: 根据规则进行抽取\u003C/li\u003E\n\u003Cli\u003E抽取代理节点: 负责维护可用抽取服务器列表及分配抽取任务\u003C/li\u003E\n\u003Cli\u003E订阅源监测节点: 负责定时检查订阅源更新，将更新地址转发给抓取节点下载并保存最后抽取结果\u003C/li\u003E\n\u003Cli\u003E订阅源代理节点: 负责维护可用订阅源监测节点、记录及分配订阅源，根据地址匹配抽取规则\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Cp\u003ERuiJi.Net 集群\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/05/2-2.png\" /\u003E\u003C/p\u003E\n","485660":"\u003Ch3\u003E\u003Ca class=\"anchor\" id=\"meta-抽取器\" href=\"#meta-抽取器\"\u003E\u003C/a\u003EMeta 抽取器\u003C/h3\u003E\n\u003Cp\u003EMeta抽取器可以用在Tile和Block下，当Tile具有Meta时, Meta被用来抽取的Tile重复结果中需要抽取的元数据，通常被用来抽取列表信息。当Block具有Meta时，Meta用来提取Block中需要提取的元数据，通常用来提取详细页的元数据。\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"当tile具有meta时-meta的抽取结果通常是多组\" href=\"#当tile具有meta时-meta的抽取结果通常是多组\"\u003E\u003C/a\u003E当Tile具有Meta时，Meta的抽取结果通常是多组\u003C/h5\u003E\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/3-1.png\" /\u003E\u003C/p\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"当block具有meta时-meta的抽取结果通常为一组\" href=\"#当block具有meta时-meta的抽取结果通常为一组\"\u003E\u003C/a\u003E当Block具有Meta时，Meta的抽取结果通常为一组\u003C/h5\u003E\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/4.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003E(~\u0026gt;__\u0026lt;~) 阅读为0\u003C/p\u003E\n","500992":"\u003Cp\u003E点击Add按钮或规则的编辑按钮可进入规则详细编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/12.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003E各字段属性对照表如下：\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E字段\u003C/th\u003E\n\u003Cth\u003E描述\u003C/th\u003E\n\u003Cth\u003E特性\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EUrl\u003C/td\u003E\n\u003Ctd\u003E提取规则的原地址\u003C/td\u003E\n\u003Ctd\u003E支持关键词搜索，方便日后参考\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EExpression\u003C/td\u003E\n\u003Ctd\u003E地址匹配表达式\u003C/td\u003E\n\u003Ctd\u003E支持关键词搜索,通配符*代表多个字符，?代表一个字符\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EMethod\u003C/td\u003E\n\u003Ctd\u003E请求方法\u003C/td\u003E\n\u003Ctd\u003EGET POST\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EUA\u003C/td\u003E\n\u003Ctd\u003E浏览器User-Agent\u003C/td\u003E\n\u003Ctd\u003E为空则随机使用\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EHearders\u003C/td\u003E\n\u003Ctd\u003E请求标头\u003C/td\u003E\n\u003Ctd\u003E以回车分割\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EFeature\u003C/td\u003E\n\u003Ctd\u003E界面特征\u003C/td\u003E\n\u003Ctd\u003E在一个界面有多重规则时，需根据界面特征进行规则选取\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EType\u003C/td\u003E\n\u003Ctd\u003E地址返回值格式\u003C/td\u003E\n\u003Ctd\u003E仅记录，无实际用途\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ERuiji Exp\u003C/td\u003E\n\u003Ctd\u003ERuiji表达式\u003C/td\u003E\n\u003Ctd\u003E详情请参照\u003Ca href=\"https://gitee.com/zhupingqi/RuiJi.Net/wikis/pages?title=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BB%8B%E7%BB%8D\u0026amp;parent=RuiJi%E8%A1%A8%E8%BE%BE%E5%BC%8F\" target=\"blank\"\u003ERuiji表达式介绍\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EStatus\u003C/td\u003E\n\u003Ctd\u003E是否开启\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ERunJs\u003C/td\u003E\n\u003Ctd\u003E是否执行页面JS\u003C/td\u003E\n\u003Ctd\u003E如果选择ON,RuiJi.Net将会使用无头浏览器对目标页面进行访问\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","504421":"\u003Ch4\u003E\u003Ca class=\"anchor\" id=\"selectorprocessor\" href=\"#selectorprocessor\"\u003E\u003C/a\u003ESELECTORPROCESSOR\u003C/h4\u003E\n\u003Cp\u003E函数选择器被用来在使用RuiJi.Net提供的标准选择器后，仍然不能满足抽取要求的场合，例如：我们经常在抓取日期的时候，取回的结果可能是时间戳或非完整的日期,也有可能遇到返回的是几分钟前或几天前，返回的结果并不是我们预期的结果，这时候可以使用SELECTORPROCESSOR来处理这样的结果。\u003C/p\u003E\n\n\u003Cp\u003E例如我们可以定义一个函数 名称为abc，内容如下\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eif (content.EndsWith(\"小时前\"))\n{{\n    var hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n    results.Add(DateTime.Now.AddHours(-hour));\n}}\n\nif (content.EndsWith(\"天前\"))\n{{\n    var hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n    results.Add(DateTime.Now.AddDays(-hour));\n}}\n\nif (content.EndsWith(\"AddMinutes\"))\n{{\n    var hour = Convert.ToInt32(Regex.Match(content, @\"[\\d]*\").Value);\n    results.Add(DateTime.Now.AddDays(-hour));\n}}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E该代码是用C#实现的，如果您仅使用RuiJi.Net.Core的核心类库, 您需要将此代码以 函数名.pro 的形式存储于执行目录的funcs文件夹，如果您使用RuiJi.Net整个项目的进行管理的话，您还可以管理界面对函数选择器进行管理\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E代码里面出现的content是当前的函数选择器上一个选择器的处理结果，通过自定义函数选择器，您可以根据您的抽取需求，对不精确的数据进行更精确的清洗。\u003C/p\u003E\n\n\u003Cp\u003E您可以在RuiJi表达式中，这样使用\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[block]\n#BlockName\ncss #topsOfRecommend:ohtml\n\n[tile]\n#titlename\ncss .box-aw\n\n    [meta]\n    ......\n\n    #postdate\n    css .blog-footer-box \u0026gt; span:eq(2):text\n    proc abc\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E我们在将来也会增加使用js实现的函数选择器\u003C/p\u003E\n\u003C/blockquote\u003E\n","490490":"\u003Cp\u003EPaging抽取器是一个特殊的抽取器，它被用来抽取页面的分页，Paging抽取器的抽取结果必须为链接地址，Paging选择器会自动按照链接出现的顺序抽取页面数据，并将[meta]中的content字段进行合并，Paging抽取器通常用于具有分页的详细页面。\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[block]\n\n......\n\n[meta]\n......\n\n#content\ncss .a-con:ohtml\n\n[paging]\ncss .a-page\ncss a[href]\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E您需要保证所抽取的页面为分页的第一页，否则分页的合并结果可能不正确\u003C/p\u003E\n\u003C/blockquote\u003E\n","490057":"\u003Cp\u003ERuiJi.Net的配置文件如下,您需要在config文件中配置这些信息\u003C/p\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E{\n  \"setting\": {\n    \"zkPath\": \"zookeeper-3.4.12\",\n    \"zkServer\": \"localhost:2181\",\n    \"ruiJiServer\": \"localhost:36000\",\n    \"docServer\": \"localhost:80\"\n  },\n  \"nodes\": [\n    {\n      \"baseUrl\": \"localhost:36000\",\n      \"type\": \"cp\"\n    },\n    {\n      \"baseUrl\": \"localhost:37000\",\n      \"type\": \"ep\"\n    },\n    {\n      \"baseUrl\": \"localhost:38000\",\n      \"type\": \"fp\"\n    },\n    {\n      \"baseUrl\": \"localhost:36001\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:36002\",\n      \"type\": \"c\",\n      \"proxy\": \"localhost:36000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37001\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:37002\",\n      \"type\": \"e\",\n      \"proxy\": \"localhost:37000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38001\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    },\n    {\n      \"baseUrl\": \"localhost:38002\",\n      \"type\": \"f\",\n      \"proxy\": \"localhost:38000\"\n    }\n  ]\n}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"setting\" href=\"#setting\"\u003E\u003C/a\u003Esetting\u003C/h5\u003E\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E名称\u003C/th\u003E\n\u003Cth\u003E说明\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EzkPath\u003C/td\u003E\n\u003Ctd\u003Ezookeeper路径\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EzkServer\u003C/td\u003E\n\u003Ctd\u003Ezookeeper地址\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EruiJiServer\u003C/td\u003E\n\u003Ctd\u003E本地模式下服务地址\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EdocServer\u003C/td\u003E\n\u003Ctd\u003E文档服务器地址\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003EzkPath 在使用自启动zookeeper时使用，您也可以不使用自管理的zookeeper\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Ch5\u003E\u003Ca class=\"anchor\" id=\"appsettings\" href=\"#appsettings\"\u003E\u003C/a\u003EappSettings\u003C/h5\u003E\n\u003Cp\u003ERuiJi.Net可以使用自管理ZooKeeper 如果指定zkPath，RuiJi.Net将会自动启动ZooKeeper\u003C/p\u003E\n\n\u003Cp\u003EzkServer 被用来告诉所有的节点 ZooKeeper 服务器的位置\u003C/p\u003E\n","500993":"\u003Cp\u003E点击Test按钮可测试提取结果，如下图所示\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如果是伪分布式或全分布式模式，请先前往Setting \u0026gt; Node设置好抓取节点可用IP\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/13.png\" /\u003E\u003C/p\u003E\n","504403":"\u003Cp\u003ERuiji.Net在请求下载页面时会模拟用户代理（User Agent，以下简称UA），并根据UA设置使用Cookie管理器生成多个Cookie进行下载。Ruiji.Net对UA设置主要分为UA组设置及UA设置。UA组代表不同PC浏览器或手机浏览器，UA则是某个UA组下的不同UA。通过此设置界面您可以对UA组及下属UA进行增删改查。这里需要注意的是删除UA组的同时也会删除其所属所有UA。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/20.png\" /\u003E\u003C/p\u003E\n","580719":"\u003Cp\u003E如果您需要运行页面上的js脚本，您需要安装chromium无头浏览器。\u003C/p\u003E\n\n\u003Cp\u003E地址为 \u003Ca target=\"_blank\" href=\"https://pan.baidu.com/s/1rsyCNnXxbobCBLZuPTiJHQ\"\u003Ehttps://pan.baidu.com/s/1rsyCNnXxbobCBLZuPTiJHQ\u003C/a\u003E 访问密码 cr3e\u003C/p\u003E\n\n\u003Cp\u003E下载RuiJi.Net所部署的操作系统对应的chromium的zip包\u003C/p\u003E\n\n\u003Cp\u003E将运行文件解压至RuiJi.Net运行目录中的chromium文件夹中\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003E如下图示例，是我发布的RuiJi.Net相对应的windows64位操作系统示例\u003C/p\u003E\n\u003C/blockquote\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/28.png\" /\u003E\u003C/p\u003E\n\n\u003Cblockquote\u003E\n\u003Cp\u003Elinux下需安装chromelib库\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eyum install chromium-libs.x86_64\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E并给与chromium文件夹最高权限\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cdiv class=\"white\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Echmod -R 777 chromium\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E","520273":"\u003Cp\u003E点击Add按钮或者选择某个UA组后点击Update按钮，可进入UA组编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/21.png\" /\u003E\u003C/p\u003E\n","520278":"\u003Cp\u003E点击Add按钮或者点击某个UA的编辑按钮，可进入UA编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/22.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003EDialog中各字段属性对照表如下\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E字段\u003C/th\u003E\n\u003Cth\u003E描述\u003C/th\u003E\n\u003Cth\u003E特性\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EGroup\u003C/td\u003E\n\u003Ctd\u003EUA组名称\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EName\u003C/td\u003E\n\u003Ctd\u003EUA名称\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EValue\u003C/td\u003E\n\u003Ctd\u003EUA具体值\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ECount\u003C/td\u003E\n\u003Ctd\u003E生成Cookie数量\u003C/td\u003E\n\u003Ctd\u003ERuiji.Net中的Cookie管理器会根据此值生成此数量的Cookie值\u003Cbr\u003E以供使用此UA时进行Cookie轮询\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","504404":"\u003Cp\u003ERuiji.Net在抓取的过程中，请求页面时，为防止被封，会采取多IP轮询制。IP代理设置可供请求页面时进行IP轮询。在此界面还可对代理进行及时测试。因代理不稳定，固每次测试结果可能不同。\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/23.png\" /\u003E\n\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/24.png\" /\u003E\u003C/p\u003E\n","520376":"\u003Cp\u003E点击Add按钮或点击某个代理的编辑按钮，可进入代理编辑界面\u003C/p\u003E\n\n\u003Cp\u003E\u003Cimg src=\"http://www.ruijihg.com/wp-content/uploads/2018/07/25.png\" /\u003E\u003C/p\u003E\n\n\u003Cp\u003EDialog中各字段属性对照表如下\u003C/p\u003E\n\n\u003Ctable\u003E\n\n\u003Ctr\u003E\n\u003Cth\u003E字段\u003C/th\u003E\n\u003Cth\u003E描述\u003C/th\u003E\n\u003Cth\u003E特性\u003C/th\u003E\n\u003C/tr\u003E\n\n\n\u003Ctr\u003E\n\u003Ctd\u003EIp\u003C/td\u003E\n\u003Ctd\u003E代理IP\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EPort\u003C/td\u003E\n\u003Ctd\u003E端口\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EUserName\u003C/td\u003E\n\u003Ctd\u003E代理登录账号\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EPassword\u003C/td\u003E\n\u003Ctd\u003E代理登录密码\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EType\u003C/td\u003E\n\u003Ctd\u003E代理类型\u003C/td\u003E\n\u003Ctd\u003EHTTP HTTPS\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EStatus\u003C/td\u003E\n\u003Ctd\u003E是否开启\u003C/td\u003E\n\u003Ctd\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\n\u003C/table\u003E\n","520378":"\u003Cp\u003E日后我们会添加Storage设置，针对存储抓取结果，可设置使用不同数据库（例如MsSqlServer、Mysql、MongoDB、Solr等）进行存储。\u003C/p\u003E\n","520379":"\u003Cp\u003E.keep\u003C/p\u003E\n"}}</script>